Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 2 years ago.
Improve this question
One mentor I respect suggests that a simple bean is a waste of time - that value objects 'MUST' contain some business logic to be useful.
Another says such code is difficult to maintain and that all business logic must be externalized.
I realize this question is subjective. Asking anyway - want to know answers from more perspectives.
The idea of putting data and business logic together is to promote encapsulation, and to expose as little internal state as possible to other objects. That way, clients can rely on an interface rather than on an implementation. See the "Tell, Don't Ask" principle and the Law of Demeter. Encapsulation makes it easier to understand the states data can be in, easier to read code, easier to decouple classes and generally easier to unit test.
Externalising business logic (generally into "Service" or "Manager" classes) makes questions like "where is this data used?" and "What states can it be in?" a lot more difficult to answer. It's also a procedural way of thinking, wrapped up in an object. This can lead to an anemic domain model.
Externalising behaviour isn't always bad. For example, a service layer might orchestrate domain objects, but without taking over their state-manipulating responsibilities. Or, when you are mostly doing reads/writes to a DB that map nicely to input forms, maybe you don't need a domain model - or the painful object/relational mapping overhead it entails - at all.
Transfer Objects often serve to decouple architectural layers from each other (or from an external system) by providing the minimum state information the calling layer needs, without exposing any business logic.
This can be useful, for example when preparing information for the view: just give the view the information it needs, and nothing else, so that it can concentrate on how to display the information, rather than what information to display. For example, the TO might be an aggregation of several sources of data.
One advantage is that your views and your domain objects are decoupled. Using your domain objects in JSPs can make your domain harder to refactor and promotes the indiscriminate use of getters and setters (hence breaking encapsulation).
However, there's also an overhead associated with having a lot of Transfer Objects and often a lot of duplication, too. Some projects I've been on end up with TO's that basically mirror other domain objects (which I consider an anti-pattern).
You should better call them Transfer Objects or Data transfer objects (DTO).
Earlier this same j2ee pattern was called 'Value object' but they changed the name because it was confused with this
http://dddcommunity.org/discussion/messageboardarchive/ValueObjects.html
To answer your question, I would only put minimal logic to my DTOs, logic that is required for display reasons.
Even better, if we are talking about a database based web application, I would go beyond the core j2ee patterns and use Hibernate or the Java Persistence API to create a domain model that supports lazy loading of relations and use this in the view.
See the Open session in view.
In this way, you don't have to program a set of DTOs and you have all the business logic available to use in your views/controllers etc.
It depends.
oops, did I just blurt out a cliche?
The basic question to ask for designing an object is: will the logic governing the object's data be different or the same when used/consumed by other objects?
If different areas of usage call for different logic, externalise it. If it is the same no matter where the object travels to, place it together with the class.
My personal preference is to put all business logic in the domain model itself, that is in the "true" domain objects. So when Data Transfer Objects are created they are mostly just a (immutable) state representation of domain objects and hence contain no business logic. They can contain methods for cloning and comparing though, but the meat of the business logic code stays in the domain objects.
What Korros said.
Value Object := A small simple object, like money or a date range, whose equality isn't based on identity.
DTO := An object that carries data between processes in order to reduce the number of method calls.
These are the defintions proposed by Martin Fowler and I'd like to popularize them.
I agree with Panagiotis: the open session in view pattern is much better than using DTOs. Put otherwise, I've found that an application is much much simpler if you traffic in your domain objects(or some composite thereof) from your view layer all the way down.
That said, it's hard to pull off, because you will need to make your HttpSession coincident with your persistence layer's unit of work. Then you will need to ensure that all database modifications (i.e. create, updates and deletes) are intentional. In other words, you do not want it be the case that the view layer has a domain object, a field gets modified and the modification gets persisted without the application code intentionally saving the change. Another problem that is important to deal with is to ensure that your transactional semantics are satisfactory. Usually fetching and modifying one domain object will take place in one transactional context and it's not difficult to make your ORM layer require a new transaction. What is challenging is is a nested transaction, where you want to include a second transactional context within the first one opened.
If you don't mind investigating how a non-Java API handles these problems, it's worth looking at Rails' Active Record, which allows Ruby server pages to work directly with the domain model and traverse its associations.
Related
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 5 years ago.
Improve this question
I'm developing a Spring Boot MVC application and, after reading many guides and comments, I still have some doubts that I have not unmarked.
1: I do not want an anemic pattern, so I do not have a monolithic service where all the services are called each other, but these communicate only with repository instantiating entity, inside which I put the business logic, correct?
2: where to put the conversion functions entitiy-> dto? I read that someone puts them in the Controller, others in the Service, others on the same domain .. at the moment the cleanest solution and I prefer to have a Builder of the DTO that lends the entity input, okay I have contraindications?
3: polymorphism and inheritance: I have a service that composes some menu levels according to an attribute of the entity in question. I do not want to have blocks of if anywhere, I wanted to be able to put this logic in a single point, to instantiate the correct class (which I do not know a priori) and to exploit the polymorphism, how can I do? considered to involve service, entity and related logic ..
thank you so much
Your questions are more related to software design in general rather than specific to the Spring framework. Allowing the framework to dictate how to organize your code, has some downsides.
But to answer your questions:
Depending on how complex and interrelated your model is, there are different options, for the cases where there is not big interdependence between the entities in the model, the 3 layer approach is simple and good enough, but if your model is more complex, you could take a look into the concept of Aggregates, and keep the invariants hidden inside.
Constructing the DTO with the Entity as parameter is a good solution, whenever changes needs to be made to either the DTO or the Entity, the amount of code to maintain is not as much as with other approaches, it is not just about the conversion code, it is also about methods signatures, and all of the usages. This approach also follows the Dependency Inversion principle which states that low level modules (presentation in this case) should depend on high level policies (business logic) and not the other way around. But it is not the only valid solution, it always depends on your concrete case.
If you want to return an object from your service that can be an instance of different types, there are different ways to do so, a way to do so (but not the only one, and again, the best way always depends on your concrete case):
For the type control, one option would be to make the method return type an interface, and then have the possible different objects that can be returned to extend that interface.
For the construction of the different objects, you can encapsulate it inside of the service in a private function if that is the only place you are going to use it, or if you are going to use it in more places, then you could extract it to a factory and use it as a colaborator of the service. For the construction you won't be able to avoid the if checks, but outside the service, once you serve the different instances, then you won't need to do more if checks.
and finally in the service return the instance that you constructed, as it implements the interface, the compiler will still be happy about it.
Hope it helps!
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 8 years ago.
Improve this question
Designing application tier is not trivial. At the end of the day, in every project we write (huge) number of so-called business methods (sometimes called service methods, although it is not related to services as in public APIs) that perform some business logic and usually do some database/storage operations (via storage tier). But designing/organizing/naming your application methods is not trivial as it sounds; people often have rules on project how application classes and methods should be designed. I am looking for pragmatic set of such rules for designing the application tier, so here are some questions:
Grouping methods in classes: by return type or?
For example, method that updates a user belongs to class eg UserService. Or method that finds a user by some criteria belongs to the same class. But what happens when some method works on several types, like e.g. registerUserForCompetition()? Should this be in UserService or CompetitionService? The same question for the method findUserCompetition() - where would you put it?
I often see a rule that says that this depends on methods return type. In our example, if method returns User (or collection of users etc) it should belong to UserService.
Method parameters: simple types (primitives, String...) or entities (e.g. User, Competition, Registration...)?
This question is often asked, and people usually (statistically:) choose the first approach, using simple types as service arguments. But what to do when one such method calls the other method on the same resource? Let me give you an example: registerUser(userId, competitionId) may internally call checkCompetition(competitionId). Both methods fetch the Competition from the storage. Obviously, this is done twice and, since we already have the Competition object we can use it to checkCompetition with it. So should we add overloaded method, or we should ignore this and just really on caching mechanism to prevent double fetching?
On the other hand, having full types as parameters can not be universal rule, as many times the full information is not needed and there is no reason to fetch the full object while you need just it's id, that you already may have it.
Naming methods: how verbose methods name should be?
Especially for finder methods. Should we have eg:
findCompetition(userId, year) or
findCompetitionWithVenue(userId, year) (since every Competition object has linked Venue); or
findCompetitionForUserAndYear(userId, year) or
findCompetitionByUserIdAndYear(userId, year) or just
findUserCompetitionForYear(userId, year)?
When number of different criteria rises, it is easy to make a mess with finder method names, and I often see rules like this: find<return-type>By<names-of-parameters> or similar.
Do you have naming convention for application classes?
Do your classes names end with Service? Do you separate managers from services, where manager deals with entities and services accept only simple types? Do you group all your business classes in the same package, or group them together with other related classes (model, controller...), based on functionality?
Please share your experience with focus on being pragmatic - for me it means that new developer can easily figure where to find business methods and how to write new ones, so everyone gets more productive. Also, if you have established rules, please share how your team is managed to follow them.
group services by functionality. in the same package should be also controler, part of model etc. there are better approaches then layered architecture. try DDD. it perfectly isolates functionality, makes it easier to find and change
usually it's good to have entities (model) hidden from the client and communicate with controllers through DTOs and ValueObjects. just in case you want to change your model in the future
they must be meaningful for your domain and consistent. and don't be affraid to refactor if your team says they are not clear. personally i would go with findCompetition(user, year) with non-primitive types because you can use method overloading but then in invocations you have to use constants or reading enablers like findCompetition(forUserId(userId), forYear(year)) to explicitly tell the reader which version you are invoking.
what is manager? it means nothing. similarly to helper, handler etc. Service contains the logic that converts DTO to entities and the logic can't be pushed to the domain/entity because the logic operates on many entities. as stated before i group components (not only services) by functionality and therefore i add the 'Service' suffix because it helps me quickly find the logic in specific package (which contains model, controller, service, repository etc)
I have an application with 3 layers: GWT-RPC, Business and DAO
In every layer I have different beans. For example for a User I'd have UserRPC (for the UI), User (business) and UserDTO (to persist). At every layer change I reconvert the objects.
The main problem are the enumerations. The enumerations are exactly the same across the layers but I need to replicate them in order to keep the layer independence.
Any suggestion?
(Short answer)
If they are truly the same you want to create a commons project / jar . Inside here are all the things that are common to the entire application, such as utility classes, enumerations, etc.
(Long answer)
Consider the overall architecture of your system, there should not be any need to have duplicated data in any tier. If this is occurring it means there is a flaw in the design of the system and a scenario of tight coupling may be on the horizon. This is part of the reason why when developing software engineers often (should) document the interfaces (contracts / api) before doing any implementation. Once these interfaces are approved and there is limited to no chance of duplication the actual implementation can begin. This would catch the scenario of X number of enumerations, which are constants, being created at each individual tier of the application. Also, keep in mind that with enumerations that if something in your business tier changes that would impact an enumeration you must recompile the code and redeploy. You must take care to not have an enumeration being used as a catch all for all of your system constants as this is an entirely different issue you may have to deal with.
The enumerations are exactly the same across the layers but I need to
replicate them in order to keep the layer independence.
Data duplication is never a good idea. How do you make sure that updates to one enumeration are reflected in other layers? You should probably create a Utility layer where you put all common classes there.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 4 years ago.
Improve this question
Its a pretty basic question but I am new to Java designing to please excuse me. :)
I want to know in which scenarios we need to separate the class behavior from the class itself.
for e.g.
If I have an class Employee, I will have some data in it like - name, age etc. Also this class will have some behavior like doWork() etc. Now in what scenario we can have data and the behavior inside once class (Employee) only and in which scenario we need to have 2 different classes for Employee data (EmployeeDTO) and behavior (EmployeeService)
Very subjective question but am looking for some inputs on a design of a small application where I am taking data from a text file. Should I put the data and behavior in different classes or same? What will be your reason to justify this decision?
PS: Any links to information on this will also be very useful :)
Thankyou
Good object-oriented design advocates that each class obey the Single Responsibility Principle. Which I can't summarize any more eloquently than the wikipedia entry:
Martin defines a responsibility as a reason to change, and concludes
that a class or module should have one, and only one, reason to
change. As an example, consider a module that compiles and prints a
report. Such a module can be changed for two reasons. First, the
content of the report can change. Second, the format of the report can
change. These two things change for very different causes; one
substantive, and one cosmetic. The single responsibility principle
says that these two aspects of the problem are really two separate
responsibilities, and should therefore be in separate classes or
modules. It would be a bad design to couple two things that change for
different reasons at different times.
If you think about it, you could jam all of your Java code into one class file, but you don't. Why? Because you want to be able to change, maintain, adapt and test it. This principle says that instead of dividing your code up arbitrarily into different modules, you should take the tact that things should be broken up by their logical responsibilities. This generally means more, small modules which we know to be easier to change, maintain, adapt and test.
I personally would recommend that you factor your code out into smaller discrete classes and combine them later if this proves to be unreasonable -- this will become obvious to you. Its much easier to combine loosely-coupled code in the future than it is to factor out tightly-coupled code.
Do the simplest thing possible. You can always make your code more generalized later and there's a good chance you won't even have to do it.
Apply YAGNI principle every time you need to make a decision. Extreme Programming wiki is also a nice reading.
Put everything into one class right now. When you see your Employee is getting too fat then you can do some refactoring - for example, move method to another class. In statically typed languages like Java it is super easy because compiler helps a lot and IDE support is great.
Reading from file, for example, looks like an obvious candidate to extract to a separate loader class. On the other hand if you have a very common format as input such as XML or JSON you could just create static method List<Employee> Employee.loadFromFile(string fileName) and implement reading logic in a couple of lines of code. It's good enough right now: simple, short and works fine.
May The Real Ultimate Programming Power be with you!
By keeping business logics out of pojo, thus making it a pure transfer object, you have the benefit of loose coupling should one day you find yourself in the situation for the need to switch from Spring framework to EJB JavaBeans.
By putting data and business logic together, it becomes a domain object. The simplest form of managed bean usage promoted in JSF2 uses the domain model whereby the "action" is fused together with form data.
If you choose the first model, you can cleanly separate concerns for designing inheritence and polymorphism for your data objects, while not being bothered if the behaviors defined are making sense, and vice versa.
You use a DTO (like the acronym suggests) when you want to move data around using the lightest weight way possible, such as over the wire to a service.
For the record
Its the classic rich domain object vs anemic domain object.
In general, if you have an UI Object or a Library Object (for example the class Date or the class TextButton), and may be some other kind of Objects then may be you can wrap all in a single Class instead of relies in different classes just for commodity to have all the attributes and methods in the same class.
However, for a classic Business Object (BO) is different. Even if you want a rich domain object, excluding some other problems that i don't want to mention at this point, is the fact that the Business Service (BS) Layer acts as a "fat burning diet plan" and it turns every rich BO into a anemic BO.
Rich BO -------> BS ----------> Anemic BO.
We are following Domain Driven Design for the implementation of a large website.
However by putting the behaviour on the domain objects we are ending up with some very large classes.
For example on our WebsiteUser object, we have many many methods - e.g. dealing with passwords, order history, refunds, customer segmentation. All of these methods are directly related to the user. Many of these methods delegate internally to other child object but
this still results in some very large classes.
I'm keen to avoid exposing lots of child objects
e.g. user.getOrderHistory().getLatestOrder().
What other strategies can be used to avoid this problems?
The issues you are seeing aren't caused by Domain Driven Design, but rather by a lack of separation of concerns. Domain Driven Design isn't just about placing data and behavior together.
The first thing I would recommend is taking a day or so and reading Domain Driven Design Quickly available as a free download from Info-Q. This will provide an overview of the different types of domain objects: entities, value objects, services, repositories, and factories.
The second thing I would recommend is to go read up on the Single Responsibility Principle.
The third thing I would recommend is that you begin to immerse yourself in Test Driven Development. While learning to design by writing tests first won't necessarily make you designs great, they tend to guide you toward loosely coupled designs and reveal design issues earlier.
In the example you provided, WebsiteUser definitely has way too many responsibilities. In fact, you may not have a need for WebsiteUser at all as users are generally represented by an ISecurityPrincipal.
It's a bit hard to suggest exactly how you should approach your design given the lack of business context, but I would first recommend doing some brain-storming by creating some index cards representing each of the major nouns you have in your system (e.g. Customer, Order, Receipt, Product, etc.). Write down candidate class names at the top, what responsibilities you feel are inherent to the class off to the left, and the classes it will collaborate with to the right. If some behavior doesn't feel like it belongs on any of the objects, it's probably a good service candidate (i.e. AuthenticationService). Spread the cards out on the table with your colleges and discuss. Don't make too much of this though, as this is really only intended as a brainstorming design exercise. It can be a little easier to do this at times than using a whiteboard because you can move things around.
Long term, you should really pick up the book Domain Driven Design by Eric Evans. It's a big read, but well worth your time. I'd also recommend you pick up either
Agile Software Development, Principles, Patterns, and Practices or Agile Principles, Patterns, and Practices in C# depending on your language preference.
Although real humans have lots of responsibilities, you're heading towards the God object anti-pattern.
As others have hinted, you should extract those responsibilities into separate Repositories and/or Domain Services. E.g.:
SecurityService.Authenticate(credentials, customer)
OrderRepository.GetOrderHistoryFor(Customer)
RefundsService.StartRefundProcess(order)
Be specific with naming conventions (i.e. use OrderRepository or OrderService, instead of OrderManager)
You've run into this problem because of convenience. i.e. it's convenient to treat a WebsiteUser as an aggregate root, and to access everything through it.
If you place more emphasis on clarity instead of convenience, it should help separate these concerns. Unfortunately, it does mean that team members must now be aware of the new Services.
Another way to think of it: just as Entities shouldn't perform their own persistence (which is why we use Repositories), your WebsiteUser should not handle Refunds/Segmentation/etc.
Hope that helps!
A very simple rule of thumb to follow is "most of the methods in your class HAVE to use most of the instance variables in your class" - if you follow this rule the classes will be automatically of the right size.
I ran into the same problem, and I found that using child "manager" objects was the best solution in our case.
For example, in your case, you might have:
User u = ...;
OrderHistoryManager histMan = user.getOrderHistoryManager();
Then you can use the histMan for anything you want. Obviously you thought of this, but I don't know why you want to avoid it. It seperates concerns when you have objects which seem to do too much.
Think about it this way. If you had a "Human" object, and you had to implement the chew() method. Would you put it on the Human object or the Mouth child object.
You may want to consider inversing some things. For example, a Customer doesn't need to have an Order property (or a history of orders) - you can leave those out of the Customer class. So instead of
public void doSomethingWithOrders(Customer customer, Calendar from, Calendar to) {
List = customer.getOrders(from, to);
for (Order order : orders) {
order.doSomething();
}
}
you could instead do:
public void doSomethingWithOrders(Customer customer, Calendar from, Calendar to) {
List = orderService.getOrders(customer, from, to);
for (Order order : orders) {
order.doSomething();
}
}
This is 'looser' coupling, but still you can get all the orders belonging to a customer. I'm sure there's smarter people than me that have the right names and links referring to the above.
I believe that your problem is actually related to Bounded Contexts. For what I see, "dealing with passwords, order history, refunds, customer segmentation", each one of these can be a bounded context. Therefore, you might consider splitting your WebsiteUser into multiple entities, each one corresponding to a context. There may arise some duplication, but you gain focus on your domain and get rid off very large classes with multiple responsibilities.