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!
Related
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)
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 9 years ago.
Improve this question
I know there's quite a bit out there on this topic, but I couldn't seem to find any that completely answers my questions. I was told to use a Service->DAO->Low level code architecture . I'm having a hard time wrapping my head around is the exact role of the Service class, will one Service class work for a Book DAO and also a user DAO? I was going to have a Service class for each, haveing the Service clas talk to the DAO, take the resulting string and store it in my Book class and User class, then send that object back to the Controller. In my thinking, the Service class is the high level class that delegates all the work to other classes. Thanks for your help.
A collection of service classes, known as a service tier, is responsible for carrying out the business logic of an enterprise application. Service classes usually don't map directly to DAOs, since they represent business operations that might involve a large number of domain objects. An example is an order-submission process, where the code responsible for accepting an order has to work with the objects representing orders, customer accounts, financial accounts, and inventory.
Separating the various business operations into different service classes is a design decision that depends on the complexity of the operations, how closely they're related, and so on. Some designers might decide that each business operation should be essentially a separate class (similar to the Command pattern), while others prefer a more comprehensive interface with a richer variety of methods.
The concept of a service tier exists to make sure that all of the business logic is stored in one place and not duplicated. Many modern systems will have several interfaces into the backend, such as a Web application (perhaps with Spring MVC Controllers), a SOAP or REST interface (perhaps with Jersey), and specialized adapters for legacy terminals or other systems. Making these interfaces all adapters around a common service tier ensures that they all behave in a consistent way and that any changes to the service tier are applied to all of the access interfaces.
In your particular case, since you're needing to ask, a single service object will probably be sufficient for your needs. It's always a good idea to list all of the service methods on a separate interface and code to that so that you can replace the implementation for testing or future upgrades.
Service class may be acting as a layer of abstraction so DAO or data layer is hidden from the "business layer".
The service may talk to multiple DAOs to perform a function in which case it's acting more of a Facade pattern, hiding the complexity of communicating with DAOs to perform the required functionality.
This sort of pattern is seen in the port and adapter or hexagonal architecture in that the business logic is insulated from lower level protocols.
http://c2.com/cgi/wiki?PortsAndAdaptersArchitecture
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 1 year ago.
Improve this question
I've been using Sonar code quality management platform for some time, and for the most cases I find it very helpful in revealing hidden design flaws of my code base.
However, there's one rule that gives me more annoyance than help and that is its check for 'cyclic package reference' violations.
I guess I fully understand where such a dependency between packages is a bad thing. For example, in a typical 3-tier presentation/service/persistence layered design, it's almost always a bad idea to let the database handling code have a reference back to UI related classes. I have no problem with calling it a 'violation'.
But let's consider other cases, i.e. like designing an IDE-like application. Say, we have a main package which contains an Application interface, which defines List<View> Application.getViews() method to reference application's views.
However, when the View interface has an Application getApplication() method to refer back to its parent application, which I believe is a quite common design, it will introduce a cyclic reference, provided each of the interfaces are separated in com.myapp.ui, and com.myapp.ui.view respectively.
Of course, you can just put the View interface into the com.myapp.ui to break the cycle. But when you have various other view related APIs in com.myapp.ui.view, many of them another abstract APIs like AbstractView, ContentView, AbstractContentView, etc. I wonder if it's more advisable to keep them in separate packages for a management purpose.
And consider the said application has many other similar cases like com.myapp.ui.action, com.myapp.ui.perspective, etc. which would really make com.myapp.ui package crowded if we are to put them all in there.
So, what approach do you suggest to handle such a situation? Are really every cyclic package references a bad thing? Or if I have to live with them, how do you configure Sonar to check only real, problematic cycles?
Every absolute -- except this one ;) -- is going to be wrong some of the time. So, is every cyclic reference bad? No. You have to use your judgement.
But if you do introduce a cyclic dependency, it's worth asking if you really need it, and why. The tl;dr is that more often than not, you may find that breaking the cycle can improve your modularity, and in particular your ability to test components separately.
To use your example, does a view really need a getApplication(), which presumably returns a relatively "heavy" object (ie, one that itself needs a database, network, etc etc)? Maybe... but maybe not. If what you really need from that getApplication is something with a few callbacks (such as when a user initiates some action), then it could be useful to create an interface in some common package for that callback. So, rather than:
com.foo.app.Application
com.foo.view.View
Application getApplication()
You'd have:
com.foo.common.Callback // maybe just a Callable, Runnable, etc?
com.foo.app.Application
provides a Callback for some action foo
com.foo.view.View
Callback getFooCallback()
The question you should be asking is: what does that give me? It could be that you have to stub out so much that it doesn't give you much -- though that may suggest you can break apart your classes some. But it could be that it actually makes it easier to test your view, because now your unit test can (1) test the view without spinning up a whole application, and (b) provide a "dummy" callback that does something like saving a string that describes the action, and then your unit test asserts that it saved the right string.
And indeed there is an open JIRA ticket to prevent considering a cycle between father/child packages as a quality flaw : http://jira.codehaus.org/browse/SONAR-3452
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.
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.