Use of interfaces in domain classes?

Asked

Viewed 684 times

7

The project analyst I’m working on as a C# programmer vigorously defends the concept of SOLID in development. And it says that one of the requirements to use it is to have interfaces for everything. Including for domain POCO classes.

As you know what is usually called a domain (in layered development) is where we place the objects that represent the entities in the database. So we have a class there Pessoa, Cliente, Produto, etc..

There is not even 1 year that I am studying . NET so I am a junior programmer. But it seems to me that using interfaces here does not bring any advantage. Only increases code and development effort.

What do you think? Does it make sense to have things like the following picture? Clarifying that our database has more than 60 tables (we have more than 70 classes to represent this database) and all with their respective interface. If, like me, you find it unnecessary, what arguments could I bring to the analyst to convince him?

código

2 answers

10


That’s a good point for discussion.. I’ll open the discussion with this answer. The purpose of an interface is to define a contract through which two components (classes, projects, services, etc.) will communicate. Okay, let’s not even get into the merits of the advantages and disadvantages now, let’s just think about the purpose: to define a contract.

Well, this serves for example for the A service, developed in any platform/ language communicate, for example using the classic stack HTML/SOAP, with service B, also developed on any platform/language. In fact, we can "understand" the protocols as an interface, if we look at their purpose, which is a common contract, but let’s get back to the subject of services...

To prevent service A sending a ball and service B waiting for a square, we define an interface, for example saying "A invokes the method Obter, passing a string which cannot be null from a maximum size of 10, and B must return a string which can be null, such as a maximum size of 100". Okay, we have an interface. Something like:

interface IExemplo {
   string Obter(string valor);
}

This is very good and I believe that no one disagrees with the benefit of using a contract. We can think of several benefits of using the interfaces:

  • To abstract the implementation. For the "A" service, no matter how (platform, language, etc.) the "B" service was implemented, as long as it complies with the contract;
  • To test is much simpler to take as reference an interface;
  • We can use dependency inversion, among other things.

Ah, before we deepen the discussion, let’s see what the principle of segregation by interfaces of S.O.L.I.D tells us:

A client should Never be Forced to implement an interface that it doesn’t use or clients shouldn’t be Forced to Depend on methods they do not use.

Or in good and clear Portuguese:

A client should never be forced to implement an interface that does not use or clients should not be required to rely on methods that do not use.

Ah, references on the good old Wiki: https://en.wikipedia.org/wiki/SOLID_(Object-oriented_design)

The "I" principle is meaning that it is better to create specific interfaces than a general one that the client will not use completely. And of course, create interfaces to decouple the client from the implementation. Note that it is not written "use interfaces everywhere"...

Now let’s focus on your POCO object. A model object, to simply carry data requires no methods, just have attributes. Who adds methods is yours Framework data access, be a ORM. Therefore, here the decoupling seems to me to be more from the point of view of the methods or your repository, which can be any BD, a file system, or anything that stores your information.

If you use a ORM (Entity Framework, NHibernate, etc.), the abstraction of the repository will already be obtained, agree?

Now let’s think about the maintenance and refactoring, other important points for S.O.L.I.D. If in the service I used as an example there is a change of business rule in the method Obter. If you change service B, in the method implementation Obter, nothing needs to be changed in the interface or service A. Great!!!!

Now what if something changes on your bank table? You have to change the interface first, then the class, and obviously your client. We did not have the benefit of the interface here, agree?

Another thing, in a POCO class without methods, the inversion of dependency seems to me meaningless too, taking a Mock of course, but only of attributes?

In the case of methods makes sense, I client, for whatever reason, I mean how and who will implement the behavior. Then yes it benefits me the interface to make a mock or a test.

That’s why, in my humble opinion, it seems to me that the place where best applies the interface is in the class that will implement the operations of the repository, its DAC (Data Access Layer), your ORM, or anything else, but not in the POCO class itself, thinking I can use dependency inversion to direct a test with mock data, or tell you which repository I want to use. So, assuming that any communication is done by interfaces indiscriminately, it doesn’t seem like a good approach, better to see where it really applies, and that doesn’t hurt the principles of S.O.L.I.D. I think the POCO class doesn’t need interfaces, again, in my humble opinion, answering your question.

One last thing: if you use a template, a T4, a code generator that manages classes/interfaces when you change the database or vice versa, even if it doesn’t make total sense to use interfaces with POCO classes, at least the maintenance part will be simplified, reducing the effort to write code, which still does not convince me to use interfaces with POCO classes.

I await other opinions, agreeing or disagreeing :-)

  • 1

    Following what you put, I found unnecessary the implementation of the interface. It seems to me that the class is not really a POCO, because in it is, in addition to the implementation of the table fields, the access methods are. I think an abstraction of the business layer would be the best use of the interface. As it is, it makes maintenance difficult, because I have to work (as you said) on the contract, then on the concrete implementation.

  • Besides, I think sometimes the principle makes it harder than it helps. Not that they’re expendable, far from it, but I think they should be better interpreted. Sometimes following design standards and/or principles to the letter can bring more bureaucracy than agility.

  • Because it is @Ricardopunctual from what I understand...and goes exactly as I think, that the central point concerns the presence or not of methods, because an interface without methods does not make sense to me. It turns out to be just bureaucracy. Thank you for the answer!

  • Only one fix, the interface cannot have fields, only methods, and it has 32 methods.

  • Class POCO? I came from Java, so that name is new to me. It has some relationship with the POJO?

  • @Maniero Peraí... what you call the field are the correct Properties? So in this example I used the class has 16 properties (read and write only) ie are 16 fields. I don’t understand what you mean, she has 32 methods.

  • 1

    @Jeffersonquesado do not know what would be POJO... rsrs But POCO is a class that represents an object in a "pure" way, without having any dependency, and can be reused in several projects. Here is a very good link explaining: http://www.eduardopires.net.br/2012/10/classes-poco/

  • Field, is field, property is property. Interfaces have no fields, only methods. Property is a set of methods (can be only one, but in this example always has 2) that can have an associated field, but on the interface never has. https://answall.com/q/89894/101 e https://answall.com/q/133924/101

  • @Grupocdsinformática tb think q if you use everywhere the principles without thinking if they are good or not for each situation disturbs

  • yes @Maniero you are right, use interfaces in classes poco, entity, dto, whatever the name, and no operations makes no sense

  • 1

    exactly @Maniero, interfaces without methods make no sense

  • 1

    What I am saying is that this interface has 32 methods. Also because there is no interface without methods. And they have to be public (maybe in C# 8 you can have private methods implemented in the interface, but it’s for something else). Read the links. So it even makes sense to look that way. It doesn’t make sense how the object that implements it will be used.

  • 1

    @Jeffersonquesado yes yes, same thing as POJO

Show 8 more comments

8

Introducing

I’ve been worried a lot about software modeling lately. I’ve been trying to improve my understanding of object orientation to go beyond what people think this paradigm is, and that almost nobody understands why they’re using it. I’ve been trying to learn new tools, and have an open view of how things can help.

But I stand by my basic philosophy that tools are meant to help you, not hinder you. And if you don’t completely master them, you don’t know if you’re helping or disturbing them.

Most people cling to certain tools and become blind to their use. I do this, everyone does. Some people do more or less. I try to do less.

Every time I become more convinced that virtually every current modeling, especially in business applications, is wrong. The shape made does not serve the purpose of Agile, OOP, SOLID, DDD, and all these tools that people lately propagate as a solution to everything.

SOLID

I almost always see this idea of Cliente, Fornecedor, etc. being used wrong (see more here, here, here and here). I almost always see inheritance being misused.

S

Ease of maintenance is given more by SOLID’s S than anything else. Be able to modularize the application is the most important thing that has. To be able to make everything stand DRY is more important. Inheritance does not usually help in this, it brings coupling and low cohesion.

The

People are naive about O. The difficulty of maintenance that O causes when it is done wrong is abysmal. In practice it is more useful when doing it differently than people believe it is inheritance. When you make inheritance practically becomes mandatory to do the O.

L

And if people understood the L most likely would not make inheritance anymore. In business domains it is very rare to work. Even legacy interface usually goes wrong.

One Pessoa is a clear object. Cliente for me is only a clear object if it contains data of the client role. If he has data of the person, for me this object does more than it should. So Cliente cannot derive from Pessoa. Including because if Fornecedor do the same, you will possibly have 2 objects for the same person, if someone can both customer and supplier at the same time.

Inclusive if the modeling is better done the impedance between the object model and the relational model is less or nonexistent. But this is another matter.

I

Let’s not forget the I. It was not applied in the question example. Did the analyst who loves SOLID so much forget this? Or he’s the kind who uses terms according to his will to show that it’s okay to do it his way.

I had a boss like that. He would quote a book to say to "prove" that his opinion was right. When I quoted the book to reason with it from something I saw for certain it said that not everything in the book was to be followed. And I agree, I just thought they were different points than he thought. Then quote a book or a principle is of no use if it doesn’t fit the solution you need.

Let’s say solve the I, then he will want to put interface?

Let’s say that the correct interface is this one. This gives little room for composition, which is what facilitates maintenance, despite the complexity of the design. Why create an interface that only serves a specific type? This seems to me to create the interface to create.

D

Using interfaces instead of concrete types is great. It even helps with SOLID D. But abusing this makes it more complicated.

SOLID is good when applied where you need it and the way you need it.

Maintenance and complex design

How people conceptualize wrong, maintenance is impaired.

When there is no problem it is because the software was too simple and did not need so much maintenance as they imagined and then a design simpler is better.

I see a lot of people doing software with design complex because it facilitates maintenance and this maintenance never happens. And when it happens the design doesn’t help as much as one imagined.

It takes a lot of experience and a lot of open mind to start doing it right. And yet you’ll always make a mistake.

It makes less mistakes who always solves the same problems. So I think I still make a lot of mistakes.

Only the person who always solves the same problems must be doing something wrong. Because there is still no universal solution to the same problems?

I see a lot of new software being done when there is already solution ready. I see a lot of developer doing repetitive work that is something less noble for a person to do. It has programmer who is almost a typist.

Interface

You know why it’s good to have this interface?

Because if one day this model is wrong just create another that meets the same interface, so you have a BeneficiarioDtoV2 refurbished and can be used in place of the BeneficiarioDto without tampering with the system and being able to live with the two.

Really? Won’t you need to tinker with the real system? Won’t the model cause several implications throughout the system? Will the interface itself need not be remodeled?

If you have to mess with the interface every time you mess with the concrete type you are doing the opposite of what SOLID preaches. All that can be inherited or implemented in derivatives can no longer move after creating, is O.

The reason there is an interface is to give consumers the ability to access a specific behavior of an object and more than that, it is not to give access to all behavior of the object, for this there is the concrete type. The interface has to be thought of how consumers benefit from it, not how the type that implements it will benefit.

The example of the question seems to me a case of trying to use interfaces for everything. And worse, even he doesn’t believe it, because there are things he prefers not to use interface, as can be seen in the model. So it’s almost random, it’s according to his taste.

You can question the use of DTO. A lot of people say this is wrong. I’m not going on the merits. But since it exists, I can’t see the advantage of the interface there, except to sniff around. There are also those who mix the business rule of the object with its mechanism. More and more I find this wrong and I think that most people can not differentiate from each other, but that is another subject.

It seems to me that the interface is being put "through doubts" in something that will hardly be necessary. This object must be consumed in very specific place.

Design perfect

If you abstract everything perfectly, it really won’t have extra consequences in maintenance. But I’ve never seen something that is perfectly abstracted. I see serious cases of abstraction, such as the cited Cliente be a Pessoa for most of the models out there. With wrong abstractions it is useless to use these techniques.

There are always solutions that can be done later. If they will be good, it is another story. Giving unnecessary solutions before is as bad as not giving necessary solutions before.

Because of SOLID and other techniques I see designs disastrous out there. Either because you don’t need it or because you do it all wrong. One believes that one understands how to apply something and that it is only apply that everything will be wonderful. Both are very mistaken presumptions usually by Dunning-Kruger effect.

To tell the truth there is no easy solution and that is guaranteed to be 100% correct.

Your project and your problem

If it is the most suitable for this project I do not know why I do not know it as a whole. And I learned that most people make mistakes because they do projects without knowing the whole. Almost all projects are like this. There is a way that "found" to ensure that everything will be easy to maintain, which is to abstract everything. Only the person gets two problems. Because it never abstracts everything as it should and will always have wrong abstractions that will hinder maintenance and will have an overly complex system and that most points will never need maintenance. At least not in what was predicted.

So don’t argue, question. Make him prove it’s necessary. It probably won’t work. But then his argument is that he did not argue why he should do something. Everything he will do should be well argued. He has to know why he is doing it. Saying it is to follow SOLID is not a plausible argument. You have to show because it will be a benefit real for the project.

You may not be able to refute his arguments. That’s something you haven’t developed yet, or you’re wrong. We can’t help that, the only solution would be for us to go there and debate with him and not you.

Of course there can always be a stalemate. He can say any nonsense and you have to accept. It can say something concrete and useful and you don’t understand. It’s part of human relationships. There’s another problem and we can’t help.

There are some subsidies to think, to question, to question him, to form your opinion with a little more basis and to argue with him. Keep asking, studying, seeing other points of view.

  • 2

    Thank you for the @Maniero reply. You said something that is a key point of what I think: "I see a lot of people making software with complex design because it facilitates maintenance and this maintenance never happens. And when it happens the design doesn’t help as much as the person imagined." It’s just my fear. Because this process has stalled the development, always with the excuse that maintenance will be SUPER easy. but you’re really gonna have that upkeep someday?

  • I was reading your answer, great points, just in relation to the DTO which I find strange.. I never did it, in fact, I versiono the whole model project with all entities/dtos, I find it more practical.

  • 1

    what you said about the tools is true. we have to take care not to become extremists. i understand that sometimes the architect does this to avoid "loopholes" and that people run away from the principles, Patterns, tools, etc, but this can be a problem, you may not analyze the best way to solve specific problems

  • I put it as a gambit, not as common practice, you don’t have to do this, but the interface is for this

  • @Still it happens to me, where I work, in more than one project... we have whole systems based on interface, generated by template of course to facilitate, but q in most layers never were using dependency inversion, tests and mocks, making only with q we have a lot of code, a lot of things aligned with standards, but no usage practice

Browser other questions tagged

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