Class association or inheritance?

Asked

Viewed 425 times

0

What better way to create an association or heritage where I have the class User and the class Academic whereas Academic is a User

User-class:

public  class Usuario 

    { 
        public int Id { get; set; }

        public int Matricula { get; set; }

        public string Nome { get; set; }

        public string Email { get; set; }

        public DateTime DataCadastro { get; set; }

        public bool Ativo { get; set; }

    }

Academic class:

 public class Academico 
{
    public int Id { get; set; }

    public Professor Professor { get; set; }

}
  • Association is usually better than inheritance.

  • Do you have a practical example for me ?

  • In C# I do not have of readiness. But soon appears someone who has.

  • Did the answer solve your question? Do you think you can accept it? See [tour] if you don’t know how you do it. This would help a lot to indicate that the solution was useful to you. You can also vote on any question or answer you find useful on the entire site.

2 answers

2

It seems to me that an academic is not a user, although he seems to be. If he is not, there is no inheritance. You can force that to be true, and some will say it is, but I wouldn’t go that way.

An academic circumstantially assumes the ability to be a user. It seems to me that they are not papers directly related one as the child of the other, but rather that stand in the way at a given time, they only associate.

People tend to look at relationships in ways that find things in common, but they’re not the same thing, they’re two different things that work together. In this case the association is more interesting.

What’s best for this case I can’t say because I don’t know everything about the problem. There are some options.

The most obvious is to associate the academic with the user creating a property or even a field that indicates which user profile he should adopt. This way you make that composition in place of inheritance. So when you need to use an academic you adopt this type. Already needs the user information he has will use the type of user, with the ease of having a direct access to it.

Eventually you may want to make a bi-directional association and make it easier for the user to access the academic. I don’t like it and may bring future problems if you change some concepts.

Ever thought that a user could be an academic and something else at the same time? Even if that’s not true today, it will never happen?

It may be that the correct thing would be to have another object that associates the various roles he assumes.

That’s why modeling correctly at first is important and should give you the flexibility to change it any way you want. You don’t control the world. You can risk that the day will always have 24 hours, even that can change, even if almost impossible, but one day someone can invent that they should have a decimal measure for the day and be accepted like that. But paper relationships can change easily. If you change, do you have to reshape the whole system? Pretty much rewrite everything that involves it?

On the other hand I may be wrong, I have little information about the problem, and even if I had enough I could still be wrong. Some degree of risk we always have.

One of the things that many people don’t understand about object orientation is that the paradigm should facilitate system modeling by giving the chance to change any part without further trauma. Only conceptualizing very well comes to that, the code is just a detail.

Nor am I saying that every system deserves this effort. It doesn’t always fit all preciousness.

If I make inheritance in this case it seems strange, but it is not absurdly wrong as occurs in many examples that we see around where the person uses inheritance to join car with banana because at a certain point he needs to use both in the same place. If that happens I think one of Ids becomes unnecessary.

So I guess it would be something like this:

public class Academico {
    public int Id { get; set; }
    public Professor Professor { get; set; }
    public Usuario Usuario { get; set; }
}

or

public class Academico {
    public int Id { get; set; }
    public Professor Professor { get; set; }
    public int UsuarioId { get; set; }
}

I put in the Github for future reference.

Note that user looks more like a composition and the teacher is an association. See more on What is the difference between Association, Aggregation and Composition in OOP?.

0

Let’s look at some possible modeling scenarios from your example and consider pros and cons.

Case relating Academico and Usuario with inheritance, I see 3 negative effects:

  1. There will be an increase in coupling between the two classes (Allowing Academico to access User attributes only through protected Getters and Setters is a way to reduce this coupling, as it gives greater freedom to change the internal structure of User without affecting Academico);
  2. You block the hierarchy of Academic heritage in languages with only simple inheritance - Academico can not inherit from another class if necessary;
  3. As for reuse, does it always make sense to say that an academic is a user? This, in particular, is a point to analyze with less emphasis, after all, you will never be able to define a 100% reusable OO model.

As a positive effect, you can use an Academy object instead of a User reference (polyformism). Here, an important point to consider is the The Liskov Substitution Principle. Wherever a user reference is used, it would make sense to use an Academic instance?

Another possible modeling would associate Academico with Usuario. In this case, my only opinion, it would be convenient to rename user to something like Credentialsso, for the sake of semantics - An academic has an access credential.

With this, you slightly reduce the coupling between the two classes (a change in the Accreditation API does not need to imply a change in the Academico API) and also does not block the Academico class for an inheritance relationship. Still, as for reuse, you could have a more generic Academic class, without the relationship with User (this would be the Academic class with the highest degree of reuse). For the system you are currently modeling, you could create a subclass of this, Academicofaculdade (just one example), which is related to Credentialsso (or User, as you prefer).

Note that the advantage you had with inheritance (polymorphism) can still be obtained through interfaces.

Although the negative effects of inheritance do not exist in the case of association, two points need to be observed:

  1. You should have an extra mechanism to ensure that, in memory, two or more academics do not associate with the same credential (if the domain does not allow this) - although this may be minimized by an existing validation during persistence (eventually you will have the object in invalid state in memory - which is not legal - but this will be discovered at the time of persistence);
  2. If you want to use the methods pertinent to the User within Academic, you must: or to invoke something as academic.Usuario.Name, which opens a little of the Academic encapsulation; or create methods in Academic that delegate to the methods already defined in User (which increases the coupling between classes).

One cannot say that one solution is more correct than another. If you choose A or B, you will only have to deal with the implications. In my systems, particularly, I prefer composition to inheritance when possible.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.