0

I’m pretty sure I’ve made some wrong assumptions in my questions so bear that in mind.

At some point, the methods inside objects that are part of the persistence layer will be called/accessed for say… retrieve some data from the persistence mechanism ( DB, noSQL, txt file, external API etc… ), where this calling is going to take place, if the persistence layer is at the bottom of the dependency chain? (Lowest policy, through “transitive dependency” depends on almost everything) Is it going to take place in the highest level policy layer (entity, business or domain layer)? or in the application layer?

I imagine the interaction with the persistence layer through a set of method calls that are named accordingly to each and every operation with the persistence mechanism, like: getUserID(x), getPostID(x) and this method to return either an object that represents a row (Active Record?) or the data as a Data Transfer Object … But as the application will eventually grow larger I, imagine the boundary interface between the application and persistence layers to grow as well, polluted with methods that once implemented represents all the operations available on the persistence mechanism, like the examples from above. Isn’t this a violation of the ISP?

3
  • Related: stackoverflow.com/q/28102970/3001761
    – jonrsharpe
    May 26, 2021 at 10:29
  • Not sure if I understand you correctly: when you wrote "At some point, the methods inside objects that are part of the persistence layer" - are you assuming your domain objects directly having methods accessing the persistence layer? The standard approach for today's enterprise application is to use a repository layer which provides separate repo objects which represent the boundary between the persistence layer and the rest of the system, so the domain objects don't contain any persistence-aware methods. Would you mind to elaborate on how this fits into your question?
    – Doc Brown
    May 29, 2021 at 7:15
  • @DocBrown Thank you for the reply. I'm pretty new to this so I may ask stupid questions. So first "are you assuming your domain objects directly having methods accessing the persistence layer?" No ... I mean I don't really know, I'm not pretty sure if I understand this correctly, but if that is the case, it means that I have to inject an persistence-related object into a domain object, right? Is that an violation on the The Dependency Rule from Clean A.? I haven't read "Patterns of EAA" so is the first time I hear about the repository layer, so that may be the answer to my question.
    – qUneT
    May 30, 2021 at 11:17

2 Answers 2

0

I guess what you are looking for is the repository pattern. The idea is to implement any persistence-related methods not inside the domain object, or some god-class-like "datastore" object, but inside repository objects, which are structured in a 1:1 manner to your domain entities. Repositories can be seen as a layer between your domain objects and the persistence layer.

So for example, if you have a User object, there is also a repository object UserRepo which contains an abstraction for the usual CRUD methods, or maybe other persistence-related operations for Userobjects. UserRepo maybe just an interface, so a specific persistence-aware implementation ("UserRepoImpl") can be mocked out for testing purposes by something like a UserRepoMock.

So what does that mean for your questions?

But as the application will eventually grow larger I, imagine the boundary interface between the application and persistence layers to grow as well, polluted with methods that once implemented represents all the operations available on the persistence mechanism.

Yes, when your application grows, there will be more domain entities, hence the repository layer will grow. But there is no "pollution" - the repo layer is exactly where all persistence operations belong.

Isn’t this a violation of the ISP?

Any part of the system which needs access to the persistence mechanics does only need to depend on the repo interfaces of the domain entities it deals with. It does not need to depend on repos for other domain entities. So no, the ISP is not violated, quite the opposite.

[do] I have to inject an persistence-related object into a domain object, right?

If the domain object contains methods which require to access the persistence layer (like User.getAllPosts()), then one has to inject a repository object into it at construction time, or just pass it at the call (User.getAllPosts(postRepository)).

Is that an violation on the The Dependency Rule from Clean Architecture?

No, since the domain objects are only using interfaces, there is no direct dependency from the domain layer to the repository layer. In the example above, the User object would depend on the interface PostRepo, but not on PostRepoImpl. See also Clean Architecture, the section about "Crossing boundaries".

2
  • Thanks for the detailed explanation, but, from my understanding, there is still something catchy, since I don't think that the interface PostRepo lives inside the domain layer, but in the persistence layer, so it still violating the Dependecy rule, because the interface that is depended on lives inside the server, not the client, the server being the persistence layer and the client that uses the interface the domain layer. But I'm sure my intuition is wrong, I'l certainly read the section "Crossing boundaries" and about the Repository pattern, thank you very mutch for your time.
    – qUneT
    May 31, 2021 at 7:08
  • @qUneT: "I don't think that the interface PostRepo lives inside the domain layer". No, it does not. "PostRepoImpl" is actually part of the persistence layer. You may rename "PostRepo" to "IPostRepo", if you think it makes it clearer (that's more a C# convention, in Java one would usually not use the "I" at the beginning).
    – Doc Brown
    May 31, 2021 at 8:08
1

It depends on how things are structured. It's possible to have a persistence layer with 1k methods and have a client that uses them all. It may not use them all equally, but that isn't relevant. That is just fine as far as the ISP is concerned. Generally as applications grow, interfaces are split into multiple interfaces based on different business objects so you don't have super huge interfaces and files.

1
  • Thanks for the reply. Haven't thought about the idea that software components, if I can call them that, are relative in size, so an interface in my application may be big, but small in context of your application, that's insightful...
    – qUneT
    May 30, 2021 at 11:20

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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