About dependency of Entity from Gateway in Clean Architecture - clean-architecture

I have a question about Gateway to Entity dependency in Clean Architecture.
I think that the following concentric figures are often introduced as clean architecture.
In the figure above, Gateway does not look directly at the Entity.
However, there is another famous illustration of Clean Architecture. (2nd figure)
When it comes to actually creating a class, I think it will have the following structure.
Looking at this, the DataAccessInterface, which has the role of Gateway, refers to the Entity.
I think that the gateway in the first figure violates the rule that it does not refer to Entity. What does this mean? ??
Also, if Gateway refers to Entity, if you want to return your own error from Gateway, you need to put your own error definition in Entity. The original error is an error specific to the application, and I feel that it does not match the domain logic. Is such a definition method correct for clean architecture? ??

The most important thing is that dependencies point inwards. That means, that the layer containing the most precious business logic should not have dependencies to the outer layers.
If the Gateway works directly with some entity from the domain (or logic layer, in the diagram you're referencing named "Entities") and has a good reason to directly access it and bypass the application layer altogether, this can be a valid and pragmatic decision.
Sometimes there is no complex application logic that might justify introducing the indirection in the application layer. However, it is good to keep an eye on such decisions and make sure the application is being refactored when the time comes that an application service that translates from the Gateway to the entity layer is making sense. Just make sure you work with what is provided by the entity (business) layer to fit the business logic and invariants. As soon as you would have to change something in your entity just to fit some needs of the outer layers this is a smell and some indirection (such as the application layer in between translating between the two layers) is definitely needed.
Concerning the error it is a similar decision. As long as the entity (in the domain
logic layer) does only have to know about errors that are meaningful from the business perspective it could be to okay directly use that error if it fits the needs of the "outside" world the Gateway is talking to
So again, it is a decision depending on your situation. Just keep in mind that it is important to NOT extend the entities in the business/domain logic layer just to fit any infrastructure related needs, such as providing different structuring of error information or additional technical details that have no meaning in the business world.

Related

Repositories (database gateway) in Clean Architecture

I have been studying Robert Martin's Clean Architecture. I loved this book, but when I saw some tutorial and code that is supposed to be an example of clean architecture, I saw a repository interface declared in the Entities (enterprise business rules) layer, with methods referencing an Entities class (which means the repository implementation in the adapters layers depends directly on Entities layer, bypassing application layer). Although in this sample codes the dependency rule is followed, i have some question about it:
Wouldn't a repository interface fit better in application layer, since persistence is more an application rule then a core rule about the entities?
In his book, and also in his blog article (search for the "What data crosses the boundaries" subtitle), Uncle bob says that only simple data structures should be passed across the boundaries, never entities. So are this sample codes wrong?
Wouldn't a repository interface fit better in application layer, since persistence is more an application rule then a core rule about the entities?
The repository interfaces are made to be used by interactors (aka. use cases). With the repository interface an interactor says what it wants but not how it is fulfilled. Thus they belong to the interactors and should therefore be placed in the use cases (application) layer.
I don't know the example you mentioned in your question, so I can't investigate it to see if there is some reason why the author put the repository interfaces in the entities layer and if it could have been solved in another way.
In his book, and also in his blog article (search for the "What data crosses the boundaries" subtitle), Uncle bob says that only simple data structures should be passed across the boundaries, never entities. So are this sample codes wrong?
Uncle Bob says
Typically the data that crosses the boundaries is simple data structures.
and later
For example, many database frameworks return a convenient data format in response to a query. We might call this a RowStructure. We don’t want to pass that row structure inwards across a boundary.
Let me explain why I highlighted typically.
So what he doesn't want in his architecture is that classes, or any types, that are defined in the database layer appear in the entities or the interactors. Because this would be a dependency from higher level modules to details.
Sometimes there are use cases that some developers want to implement more relaxed, but it comes at a price.
E.g. when you have a Show order details and you have loaded the complete order entity in your interactor, you usually have to copy almost all data to the data structure that passed the boundary (the output port) in order to strictly follow the architecture.
You could also pass the entity to the output port, but this would violate the strict architecture rules. So if you want to follow the strict rules you must copy the data to a new data structure, if not you pass the entity to the output port.
But before you pass the entity directly to the output port, you should consider the pros and cons.
If you pass the entity to the output port, ou have a dependency from the interface adapters layer to the entity layer. The dependency rule that each dependency should point inwards is still applied, but the dependency skips one layer.
Such a relaxed architecture introduces the risk that e.g. controllers might invoke business methods on entities and that is what they shouldn't do. It's up to you to decide if you (and your colleagues) are diciplined enough to not invoke business methods from the controller or if you better protect yourself and others from doing it by introducing a new data structure and do the copy effort.
From my point-of-view, which is a little more influenced by Domain-driven Design not only Clean Architecture, I see repositories as clear members of the domain layer (or business or core layer mostly referred to in clean architecture).
There are mainly two reasons for that:
1. Repositories are domain services that contain logic that has a meaning to business people.
Like finding an entity (aggregate) based on different criteria. For instance, a customer support employee, when on a support call, might have to search for an order either by the order number or if the customer does not have that they have to search by customer name and other criteria. The order repository would provide something like findOrderByCustomerName() which reflects the business language and needs. So repositories can contain more than just methods to retrieve the entity and save the entity. In some cases they can also provide a primitive value. For instance, a repository for incident tickets could give you the number of unresolved tickets for a specific product. Again, it needs to fulfill some business logic related purpose.
2. The domain (business) layer itself might need to consume a repository in order to perform some business logic.
If business logic does not fit with one single entity it is often the case that some kind of domain service is needed that contains the required logic. And this service containing business logic could need access to a repository to fulfill its tasks.
Let's say we have some company internal meeting room reservation application. If you want to make a new appointment there might be business logic that says that it must not be possible to schedule an appointment if there is already another appointment at the same time in the same meeting room. So the domain logic to ask if the requested meeting room is still free at that time might be part of the meeting room repository providing something like IsRoomFreeAt(RoomId roomId, DateTime requestedMeetingTime). And there could be a service in the domain layer executing all the related business logic which needs this repository's functionality. Even if you don't want to apply that query pattern and rather just search for the respective meeting room and do check the free status of that room instead, it would be the same result.
If the one approach or the other would be more suited for the respective application use case is another question. The important part here is that the business logic to make sure no rooms are double booked requires some information from a repository, no matter how.
If the repository would be located in the application layer the dependencies would no longer be pointing inwards because now the domain (business) layer would have a dependency on the application layer and not just the other way around.

Where to put such business logic? Service vs DAO?

Given:
Spring MVC - Hibernate.
Controller -> Service -> DAO
Now I have a method which retrieves something from the DB and EVERYTIME it does this, has to do another method say "processList" (something like just changing some values in the list depending on some screen parameters).
Question:
What layer do I put this "processList"? (Controller, Service or DAO? and why)
I really need some j2ee clarifications now, I know that MVC is the same across languages but I just need to be sure :) If I am doing this in .net I would have undoubtedly put this in service.
This really depends on what processList is doing exactly. There is no golden rule. Some rules I try to follow are:
Never make calls between main objects on the same layer.
ManagementServiceImpl should never call NotificationServiceImpl.
Don't make circular dependencies between objects.
This is very similar to the one above.
If you find yourself repeating some logic across multiple main object, try to restructure the code and extract it in specialized logical classes (this will improve unit-testing as well).
E.g. UserUpdateHandler or NotificationDispatcher (these are still owned by the service layer -> noone else is allowed to call them)...
Put the code where it logically belongs.
Don't get distracted by the fact, that some class needs to do something. It might not be the right place for the code.
Never write fully generalised code before you need to.
This has its term as premature generalisation, which is a bad practice similar to premature optimisation. Saving few lines of code now can lead to pulling your hair out in the future.
Always write code which is able to become generalised.
This is not a contradiction with the previous. This says - always write with generalisation in mind, however don't bother with writing if it is not needed. Think ahead, but not necessarily act ahead.
Leave business logic to service layer, data persistence logic to data layer and user interaction logic to presentation layer.
Don't try to parse user input in service layer. This does not belong there similarly as counting final price in e-shop application does not belong to presentation layer.
Some examples for processList:
Example I - fetching additional relations via Hibernate#initialize
This is something which is really in between the service and DAO layer. On older projects we had specialized FetchHandler class (owned by service layer). In newer projects we leave this completely to DAOs.
Example II - go through list and add business validation messages to the result
service layer, no doubt
Example III - go through the list and prepare UI messages based on the validation errors
presentation layer
Side note:
MVC is a different thing from three-layered architecture.
M model spans across all three layers. Presentation layer includes both V views and C controllers.

How to best represent database views/summary info in "3-Tiered" application

This is basically asking the same question as in How to handle views in a multilayer-application. However, that post didn't receive much feedback.
Here's the problem: we have built a 3-tiered web application with the following tiers:
-Data Access (using repositories)
-Service
-UI (MVC 3)
DTO's are passed between the UI (Controller) Layer and Service Layer. Heavier Domain Models, containing a lot of domain-level logic, are passed between the Service and Data Access Layers. Everything is decoupled using IOC and the app follows SOLID principals (or tries too) --a big happy decoupled family!
Currently the DTO->Domain Model and Domain Model->DTO conversion happens all in the service layer.
So, finally to my question:
We are going to need to start displaying more complex read-only subsets of information, (i.e. summary views joining multiple entities doing rollup totals, etc). So what is the best practice for representing this type of read-only data in the n-tiered system? Having to map read-only Domain Model types to DTO types in this case doesn't make sense to me. In most cases, there would be no difference between the 2 types anyway. My thought would be to "break" the layering boundaries for these read-only types, having the Data Access Layer serve up the DTO's directly and pass those through to the Service Layer and on to the UI.
Can anyone point me in the right direction?
Much Thanks!
Your thought on breaking the layering for reading and then displaying values make sense completely. After all, the architecture/design of the system should help you and not the other way around.
Displaying report-like data to the user should be queried simply from the database and pushed to the view; no domain/dto conversion, especially if you're in a web app. You will save yourself a lot of trouble by doing this.
Personally, I had some attempts to go through these mappings just to display some read only data and it worked poorly; the performance, the unnecessary mappings, the odd things I had to do just to display some kind of report-like views. In this case, you'll likely have your domain model and a read model. You can look up CQRS pattern, it might guide you away from thinking that you want to use the same data model for both writes and reads.
So, to answer you question, I believe that in this case the best way would be to skip layering and read DTOs directly from the database through a thin layer.

Developing N-Tier App. In what direction?

Assuming the you are implementing a user story that requires changes in all layers from UI (or service facade) to DB.
In what direction do you move?
From UI to Business Layer to Repository to DB?
From DB to Repository to Business Layer to UI?
It depends. (On what ?)
The best answer I've seen to this sort of question was supplied by the Atomic Object guys and their Presenter First pattern. Basically it is an implementation of the MVP pattern, in which (as the name suggests) you start working from the Presenter.
This provides you with a very light-weight object (since the presenter is basically there to marshal data from the Model to the View, and events from the View to the Model) that can directly model your set of user actions. When working on the Presenter, the View and Model are typically defined as interfaces, and mocked, so your initial focus is on defining how the user is interacting with your objects.
I generally like to work in this way, even if I'm not doing a strict MVP pattern. I find that focusing on user interaction helps me create business objects that are easier to interact with. We also use Fitnesse in house for integration testing, and I find that writing the fixtures for Fitnesse while building out my business objects helps keep things focused on the user's perspective of the story.
I have to say, though, that you end up with a pretty interesting TDD cycle when you start with a failing Fitnesse test, then create a failing Unit Test for that functionality, and work your way back up the stack. In some cases I'm also writing Database unit tests, so there is another layer of tests that get to be written, failed, and passed, before the Fitnesse tests pass.
If change is likely, start in the front. You can get immediate feedback from shareholders. Who knows? Maybe they don't actually know what they want. Watch them use the interface (UI, service, or otherwise). Their actions might inspire you to view the problem in a new light. If you can catch changes before coding domain objects and database, you save a ton of time.
If requirements are rigid, it's not as important. Start in the layer that's likely to be the most difficult - address risk early. Ultimately, this is one of those "more an art than a science" issues. It's probably a delicate interplay between layer design that creates the best solution.
Cheers.
I'd do it bottom up, since you'll have some working results fast (i. e. you can write unit tests without a user interface, but can't test the user interface until the model is done).
There are other opinions, though.
I would start modeling the problem domain. Create relevant classes representing the entities of the system. Once I feel confident with that, I'd try to find a feasible mapping for persisting the entities to the database. If you put too much work into the UI before you have a model of the domain, there is a significant risk that you need to re-work the UI afterwards.
Thinking of it, you probably need to do some updates to all of the layers anyway... =)

Does the MVC pattern describe Roles or Layers?

I read a text recently saying the MVC pattern describes the layers in an application. But personally I see MVC showing several key roles in an application.
Which word do you think is better, layer or role, to describe the three main pieces of MVC?
Layers should imply a very narrow coupling between the respective sets of code. MVC involves relatively tight coupling between the model, view, and controller. Therefore, if you characterize this as a layering pattern, it becomes problematic in terms of defining an API between the layers. To do this properly, you would have to implement some unintuitive patterns.
Because of this, I would agree with your tendency to view it as a pattern that defines roles within a single layer.
I think roles is a better description. The view and the controller are both in the same "layer" and usually the model is described as a layer but is used between layers.
Usually my applications are centered around the domain model with stuff like presentation, persistence and file-io around it. Thinking about an architecture as layered doesn't really work for me.
MVC clearly defines ROLES. these are 3 roles you can implement in any number of layers. For example u can have a multi layer controller
Roles, not layers. Layers are completely dependent on the underlying implementation of the MVC pattern. For instance, a service layer may be a single layer on one implementation, but it could have a web service remoting layer and a database layer (for two differing service layers) on another implementation. The concept of layers is just to help you organize it, as is the pattern, but layers are not as easy to spot as patterns, and layers can change, whereas the pattern remains the same despite the layers changing due to different implementations.
You cannot compare those two words, because they describe different concepts.
To me, a layer is something opaque that offers some functions I can use to do things. For example, a good hardware layer for a wireless transmitter would just give me a send and a receive-function (based on bytes, for example), hiding all the ugly, ugly details from me.
A role is a way an object will behave. For example, a transformation in one of my compilers is going to take an abstract syntaxtree and return an abstract syntaxtree or an affection in my current project is going to take a state-difference and return a specifically altered state-difference.
However, coming with those two definitions, I do not see the need to chose a single "correct" term and burn the other as wrong, because they don't conflict much. A part of a layer has a certain role, and a set of objects conforming to certain roles form a layer. Certainly, the controller forms a certain layer between the UI and the model (at least for input), however, ot also has a role - it turns certain event into certain other events (and thus, it is some sort of adapter).
I think either can be reasonably argued for, but I think describing the parts as "layers" is more consistent with other conventions, like the OSI model. Since the View, Controller, and Model get progressively closer to your data, it's more of a layered structure. It seems that "roles" would apply to different parts of an application on the same layer.
Why not Both? I see it as 3 separate layers implementing 3 different roles.
It's all terminology, but I think the correct software architecture term would be "layer", as in logical layer. You could use the term "architectural layer" if it is clearer.
The thing is, it's just a different way of slicing an application: a classic n-layer app would be:
UI
Business Logic
Persistence
You could have the following logical layers in a simple MVC application:
UI
Controller
Model
Persistence
But you could still talk about the "UI" and "Controller" together as forming the User Interface layer -- I usually split out the Controller into a separate layer when describing and diagramming these architectures, though.

Resources