1

I have been using AngularJs since a long time. Me and my team makes heavy use of services for retrieving the remote resources like Users which intern uses $http service so, basically, for each entity, I have services which fetches/stores etc that entity.

I was thinking why not the entity itself should be able to do that and services should be totally removed. I don't know if I am going in that direction but I need to know the opinion of others.

  • BTW, is Repository a kind of Service? – Basilevs Jul 10 '17 at 4:51
  • 2
    I was thinking why not the entity itself should be able to do that. It's named Active Record design pattern. It's considered anti-pattern by several reasons. – Laiv Jul 10 '17 at 6:39
  • How about doing one service per backend rather than one service per class/resource? That way you're not overdoing it, while still ensuring that you're never left with invalid objects (e.g. creating a user with a user ID that doesn't exist). – Mario Jul 10 '17 at 6:52
  • 1
    @Laiv: if you're going to declare an antipattern, be prepared to explain your reasons. Simply stating that something is bad without explaining why is pointless and unproductive. – Robert Harvey Jul 10 '17 at 23:46
  • Well, the intention was to give a few hints about the subject and let the OP to do a little research. There's a lot of literature about the subject. I considered that I could not say anything relevant about the pattern that had not already been said before. If the pattern is good or not, IMO is something we have to figure out by ourselfs. The same happens with anti-patterns, you can come to your own conclusions or just belive what others says. – Laiv Jul 11 '17 at 4:01
3

Extensive use of "service" is indicative of bad OOP. However, the nature of development sometimes make service-like classes unavoidable, such as in your case.

Your user entity should not be responsible for storing or retrieving itself; storing itself does not violate OOP, however, it violates many good architectural practices such as separation of concerns and the single responsibility principal. Allowing an object to store and retrieve it self will make your application very brittle, and hard to maintain.

You will need storage and retrieval service; however, simply labeling it a service is somewhat lazy imo. OOP is about nouns that verb; let's make this service a little more OOP...

An object that is responsible for only CRUD is called a repository. It should not contain anything other than CRUD methods. If you find your repository having a method like GiveUserPermission you are violating the repository pattern, it does not belong there; it either belongs in the User class or a mediator class of User and Permission. Each entity should have its own repository. A repository should not be responsible for multiple entities. And remember, it is per entity, not per table.

It is irrelevant whether your repository gets its data from a database or a http rest call; the rest of your application should be ignorant to this detail.

  • So, If I need to get all images of an user, then which repository is responsible for it? users or images? – CodeYogi Jul 16 '17 at 18:38
  • @CodeYogi It depends, I need more info on what you are making. But it does not belong in the user repository. You need to think about what kind of image it is and what it represents in your application. – TheCatWhisperer Jul 17 '17 at 14:23
  • Ok, lets say I have hotel and a hotel can have many images like we see on booking.com – CodeYogi Jul 17 '17 at 17:15
  • In this case, you would have HotelImageRepository which returns to you a list of HotelImages objects associated with a particular hotel. You would then use the keys of those objects to retrieve the actual image data as needed from an image loader. – TheCatWhisperer Jul 17 '17 at 17:36
  • In your example above GiveUserPermission is a method that needs to interact with database table or tables and by your definition there needs to be a repository in that case what should I name it? – CodeYogi Aug 18 '17 at 20:38
0

In DDD entities do not load themselves from the repository, that's the responsibility of an Application service. It is done this way in order to keep the entities pure, with no side effects. In this way you gain at least two advantages: 1) they are more testable and 2) the command operations are retry-able (this combined with optimistic locking is a big step for scalability).

However, the front-end is not a classic candidate for the Aggregate tactical design pattern (if you use AngularJs as a client application as opposed to a nodejs back-end application). So you probably enforce the business rules in the server side of your application, for security reasons. This means that your front-end just sends commands to the back-end application where you have an Aggregate that in turn change state according to the business rules and it does not have business rules that must be enforced. In best case, you have some business rules duplicated for a better UX.

In conclusion, in the front-end you don't have DDD entites/aggregates so you can use any loading pattern you want.

  • 2
    Not all OOP is DDD – TheCatWhisperer Jul 10 '17 at 18:02
  • @TheCatWhisperer of course, but the context is DDD (see the question's tags) – Constantin Galbenu Jul 10 '17 at 18:21
  • My apologies, I did not notice – TheCatWhisperer Jul 10 '17 at 18:23
  • Despite the tags, the question has nothing to do with DDD – Laiv Jul 11 '17 at 6:43
  • @Laiv then remove that tag – Constantin Galbenu Jul 11 '17 at 7:19

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.