How do i avoid, that the domain layer knows the adapters? - clean-architecture

Let's say i have a usecase (business logic), an adapter (database) and a domain object. I need to call the database from my domain logic, but the question is how. The way a do it right now is by giving the domain the adapter: (1. variant)
function usecase(adapter, domain):
domain(adapter)
function domain(adapter):
[some logic]...
adapter.save_to_database()
[more logic]...
call usecase(adapter, domain)
Now in order to avoid letting the domain logic know the adapter, i would need to return all data and call the adapter from the usecase: (2. variant)
function usecase(adapter, domain):
data = domain.some_logic()
other_data = adapter.save_to_database(data)
domain.more_logic(other_data)
call usecase()
So, everytime i use an adapter, i need to exit the domain, in order to call the adapter. Is that correct? If, so why is it better than the solution above?

In your first variant, you can call the "infrastructure" layer from the domain layer. But when you call it from the domain, you have only to use an interface (#see Dependency inversion principle, API, SPI).
If you want to call the infrastructure layer from the use case (application layer), it's possible. But prefer the first solution when you have business logic in your feature.
Some rules :
when you have business logic, use the domain layer even if you call the infrastructure layer.
when you don't have business logic, you can call the infrastructure from the application layer.

Related

diffrence between persistence layer and bussiness logic layer

Persistence layer is a group of files which is used to communicate between the application and DB. 2. Business logic layer is the rules of how to retrieve the data information from the database, and then the sever takes those information to display on the user presentation layer
This two layers look the same
What do they mean in real scenario? Also do they have difference in code?
The idea for layering a system is isolation. One layer is independent of the other.
How many different Databases are out there? Postgresql, MySql, MongoDB, Cassandra...
The persistence layer (or Data Access Layer) will provide an interface to your your system.
Let's say you system needs to find an User by its ID.
public interface UserRepository {
User findByID (Long id);
}
For each database, the implementation will change, but for the application consuming it, does it really matter? No, as long as the contract provided by the interface is not broken.
Once you have the data, the business logic will dictate what and how you will deal with it. For a MVC point of view, the business logic also defines the transaction scope (more at: Why we shouldn't make a Spring MVC controller #Transactional?).
Let's say that you have your User that you retrieved using the previous interface. But you need to return additional attributes, for example, its salary. But there is no Salary Attribute on the User POJO. And also, to calculate the salary, you system needs to call an external system. Your business logic will take care of that and then return the condensed object (known as Data Transfer Obejct) to the caller.
Some resources:
https://blog.cleancoder.com/uncle-bob/2012/08/13/the-clean-architecture.html

Domain, DAO and Service layers

I need to learn the difference between the type of methods (in term of business logic) that should be inside the Domain, DAO and Service layers objects.
For example, if I am building a small web application to create, edit and delete customers data, as far as I understand inside Domain layer object I should add methods that Get/Set Customers object properties, for example (getName, getDOB, setAddress, setPhone...etc).
Now what I am trying to learn is what methods shall I put in DAO and Service layers objects.
Thanks in advance for your time and efforts.
Speaking generally (not Hibernate or Spring specific):
The DAO layer contains queries and updates to save your domain layer into your datastore (usually a relational DB but doesn't have to be). Use interfaces to abstract your DAO away from the actual datastore. It doesn't happen often, but sometimes you want to change datastores (or use mocks to test your logic), and interfaces make that easier. This would have methods like "save", "getById", etc.
The Service layer typically contains your business logic and orchestrates the interaction between the domain layer and the DAOs. It would have whatever methods make sense for your particular domain, like "verifyBalance", or "calculateTotalMileage".
DAO: "wrapper" methods for "wrapping" JPA or JDBC or SQL or noSQL calls or whatever for accessing DB systems.
Domain: Business logic calls correlated to a single type of entities (domain objects).
Service: Business logic calls correlated to a group of type of entities or to a group of several entities of the same type.
(I'm not sure about English, sorry.......)
It means:
Service layer is "bigger" than Domain layer, is often close to front-end, often calls or uses several domain objects.
Domain objects encapsulate most stuff for one part of the domain (that's why they are called D.O.)
DAO is just sth technical, sometimes needed, sometimes not.
When real domain objects are used, then often "repositories" are used to hide access to database systems, or adding special db functionality or whatever.
front-end --> service method 1 --> d.o. A of type X, d.o. B of type X, List

Domain driven design is confusing

1) What are the BLL-services? What's the difference between them and Service Layer services? What goes to domain services and what goes to service layer?
2) Howcome I refactor BBL model to give it a behavior: Post entity holds a collection of feedbacks which already makes it possible to add another Feedback thru feedbacks.Add(feedback). Obviosly there are no calculations in a plain blog application. Should I define a method to add a Feedback inside Post entity? Or should that behavior be mantained by a corresponing service?
3) Should I use Unit-Of-Work (and UnitOfWork-Repositories) pattern like it's described in http://www.amazon.com/Professional-ASP-NET-Design-Patterns-Millett/dp/0470292784 or it would be enough to use NHibernate ISession?
1) Business Layer and Service Layer are actually synonyms. The 'official' DDD term is an Application Layer.
The role of an Application Layer is to coordinate work between Domain Services and the Domain Model. This could mean for example that an Application function first loads an entity trough a Repository and then calls a method on the entity that will do the actual work.
2) Sometimes when your application is mostly data-driven, building a full featured Domain Model can seem like overkill. However, in my opinion, when you get used to a Domain Model it's the only way you want to go.
In the Post and Feedback case, you want an AddFeedback(Feedback) method from the beginning because it leads to less coupling (you don't have to know if the FeedBack items are stored in a List or in a Hashtable for example) and it will offer you a nice extension point. What if you ever want to add a check that no more then 10 Feedback items are allowed. If you have an AddFeedback method, you can easily add the check in one single point.
3) The UnitOfWork and Repository pattern are a fundamental part of DDD. I'm no NHibernate expert but it's always a good idea to hide infrastructure specific details behind an interface. This will reduce coupling and improves testability.
I suggest you first read the DDD book or its short version to get a basic comprehension of the building blocks of DDD. There's no such thing as a BLL-Service or a Service layer Service. In DDD you've got
the Domain layer (the heart of your software where the domain objects reside)
the Application layer (orchestrates your application)
the Infrastructure layer (for persistence, message sending...)
the Presentation layer.
There can be Services in all these layers. A Service is just there to provide behaviour to a number of other objects, it has no state. For instance, a Domain layer Service is where you'd put cohesive business behaviour that does not belong in any particular domain entity and/or is required by many other objects. The inputs and ouputs of the operations it provides would typically be domain objects.
Anyway, whenever an operation seems to fit perfectly into an entity from a domain perspective (such as adding feedback to a post, which translates into Post.AddFeedback() or Post.Feedbacks.Add()), I always go for that rather than adding a Service that would only scatter the behaviour in different places and gradually lead to an anemic domain model. There can be exceptions, like when adding feedback to a post requires making connections between many different objects, but that is obviously not the case here.
You don't need a unit-of-work pattern on top on the NHibernate session:
Why would I use the Unit of Work pattern on top of an NHibernate session?
Using Unit of Work design pattern / NHibernate Sessions in an MVVM WPF

Why use service layer?

I looked at the example on http://solitarygeek.com/java/developing-a-simple-java-application-with-spring/comment-page-1#comment-1639
I'm trying to figure out why the service layer is needed in the first place in the example he provides. If you took it out, then in your client, you could just do:
UserDao userDao = new UserDaoImpl();
Iterator users = userDao.getUsers();
while (…) {
…
}
It seems like the service layer is simply a wrapper around the DAO. Can someone give me a case where things could get messy if the service layer were removed? I just don’t see the point in having the service layer to begin with.
Having the service layer be a wrapper around the DAO is a common anti-pattern. In the example you give it is certainly not very useful. Using a service layer means you get several benefits:
you get to make a clear distinction between web type activity best done in the controller and generic business logic that is not web-related. You can test service-related business logic separately from controller logic.
you get to specify transaction behavior so if you have calls to multiple data access objects you can specify that they occur within the same transaction. In your example there's an initial call to a dao followed by a loop, which could presumably contain more dao calls. Keeping those calls within one transaction means that the database does less work (it doesn't have to create a new transaction for every call to a Dao) but more importantly it means the data retrieved is going to be more consistent.
you can nest services so that if one has different transactional behavior (requires its own transaction) you can enforce that.
you can use the postCommit interceptor to do notification stuff like sending emails, so that doesn't junk up the controller.
Typically I have services that encompass use cases for a single type of user, each method on the service is a single action (work to be done in a single request-response cycle) that that user would be performing, and unlike your example there is typically more than a simple data access object call going on in there.
Take a look at the following article:
http://www.martinfowler.com/bliki/AnemicDomainModel.html
It all depends on where you want to put your logic - in your services or your domain objects.
The service layer approach is appropriate if you have a complex architecture and require different interfaces to your DAO's and data. It's also good to provide course grained methods for clients to call - which call out to multiple DAO's to get data.
However, in most cases what you want is a simple architecture so skip the service layer and look at a domain model approach. Domain Driven Design by Eric Evans and the InfoQ article here expand on this:
http://www.infoq.com/articles/ddd-in-practice
Using service layer is a well accepted design pattern in the java community. Yes, you could straightaway use the dao implementation but what if you want to apply some business rules.
Say, you want to perform some checks before allowing a user to login into the system. Where would you put those logics? Also, service layer is the place for transaction demarcation.
It’s generally good to keep your dao layer clean and lean. I suggest you read the article “Don’t repeat the DAO”. If you follow the principles in that article, you won’t be writing any implementation for your daos.
Also, kindly notice that the scope of that blog post was to help beginners in Spring. Spring is so powerful, that you can bend it to suit your needs with powerful concepts like aop etc.
Regards,
James

in MVC/MVP/MVPC where do you put your business logic?

in the MVC/MVP/MVPC design pattern where do you put your business logic? No, I do not mean the ASP.NET MVC Framework (aka "Tag Soup").
Some people say you should put it in the "Controller" in MVC/MVPC or "Presenter". But, others think it should be part of the Model.
What do you think and why?
This is how I see it:
The controller is for application logic; logic which is specific to how your application wants to interact with the domain of knowledge it pertains to.
The model is for logic that is independent of the application. i.e. logic that is valid in all possible applications of the domain of knowledge it pertains to.
Hence nearly all business rules will be in the model.
I find a useful question to ask myself when I need to decide where to put some logic is "is this always true, or just for the part of the application I am currently coding?"
The way I have my ASP.NET MVC application structure the workflow looks like this:
Controller -> Services -> Repositories
The Services layer above is where all the business logic takes place. If you put your business logic in your Controller layer, you lose the ability to re-use that business logic in other controllers.
I don't believe it belongs in the controller, because once it's embedded there it can't get out.
I think MVC should have another layer injected in-between: a service layer that maps to use cases. It contains business logic, knows about units of work and transactions, and deals with model and persistence objects to accomplish its tasks.
The controller has a reference to the service that it needs to fulfill its use case. It worries about unmarshalling requests into objects the service can deal with, calls the service, and marshals the response to send back to the view.
With this arrangement, the service is usable on its own even without the controller/view pair. It can be a local or remote object, packaged and deployed any way you wish, that the controller deals with.
The controller now becomes bound more closely to the view. After all, the controller you'll use for a desktop is likely to be different than the one for a web app.
I think this design is more service-oriented.
Put your business logic in domain and keep your domain separte. I prefered Presenter -> Command (Message command use NServiceBus) -> Domain (with BC Bounded Context) -> EventStore -> Event handler -> Repository (read model). If logic is not fit in domain then use service layer.
Please read article from Martin fowler, Eric Evan, Greg Young and Udi dahan. They have define very clear picture.
Here is article written by Mark Nijhof : http://elegantcode.com/2009/11/11/cqrs-la-greg-young/
By all means, put it in the model!
Of course some of the user interaction will have to be in the view, that will be related to your app and business logic, but avoid this as much as possible. Ironically following the principle of doing as little as possible as the user is 'working' in your GUI and as much during 'submit' or action requests makes for a better user experience and usability, not the other way around. At least for line-of-business apps.
You can put it in two places. The Controller and in the Presentation layer. By having some of the logic in the Presentation layer, you can limit the number of requests back into the architecture which adds load to the system. Yeah, you have to code twice, but sometimes this is what you need for a responsive user experience.
I kinda like what was said here (http://www.martinhunter.co.nz/articles/MVPC.pdf)
"With MVPC, the presenter component of the MVP model is split into two
components: the presenter (view control logic) and controller (abstract purpose control logic)."

Resources