I need to generate and then perform a complex sql-query which is going to access multiple databases to create some general report. This implies that the query's not related to a specific DAO object.
So where should I put the logic of executing such a query and returning result as DTO? If I create ReportDao interface and then implement it it may lead another developer into troubles, beucasu I think they will expect the Dao object tied with some table in the database.
!Opinion warning!
A DAO does not necessarily have to be linked to a specific domain class. No domain class lives in isolation, and if one presumes a DAO to only include operations on one table/domain class, one is in for a surprise, since operations might pertain to multiple domain classes, and thus be wrongly placed no matter where you put it. It's better to also think of a DAO as a collection of methods pertaining to a certain area of functionality. If most Dao are modeled around domain objects it might be wise to name the different one a bit differently, but ReportDao should be fine as long as we're talking about a collection of methods pertaining to reports/reporting. Or maybe "GeneralReportDataDao" is better (keep in mind that I only have the information in your question to work with, think about what the class represents and try to find a descriptive name..)
Another point I have seen from experience when organizing DAOs after domain classes, is that the DAOs pertaining to central domain classes tends to grow very large, since central domain classes are often linked to large amounts of functionality. This is not only true for DAO-classes, but also for Services, etc, using the same pattern for organizing functionality.
We mainly have two "types" of classes in Java, we have classes that represent something (classes containing data, typically stateful classes), and classes that do something (service, dao, etc, typically stateless classes). The stateful data classes should be named and modeled after what they represent, i.e. the data, while the stateless service classes should be named and modeled after functionality. While it is tempting to try to organize services the same way as data, it often leads to poor code, with large classes and areas of functionality spread across several classes.
Related
I (think I) just understood the differences between Java Entity, VO, POJO, Javabeans, DAO, DTO, etc, I mean, the theory. Now, I'm trying to understand the implications of the implementations depending on the needs. Who cares if I create a POJO or a JavaBean? At the beginning I will create a POJO if I have no other constraint, until I realise I must make it a Javabean and deal with it's restrictions.
When do you tell yourself: "I need a DTO"? Only for web services or when any client/server call is made? In that case, do you put all the data you need (and the one you think you will need?) in one DTO bunch?
Lastly, in a MVC model, where does each one go? Can I make an entity or a vo in either layer? Where does the DTO go?
Thank you very much
You understood the difference between them, now you need to understand their purpose.
There is a neat definition for each one in this link.
Who cares if I create a POJO or a JavaBean? At the beginning I will create a POJO if I have no other constraint, until I realise I must make it a Javabean and deal with it's restrictions.
You need to think what the purpose of the class is. Is it a standalone class with no annotations that provides functionality but can be isolated (not counting libraries used)? Then it is likely a POJO.
Is it a class that serves as a bridge between layers of your project? Is it annotated? Does it implement some business logic for your project? Then it is a JavaBean.
When do you tell yourself: "I need a DTO"? Only for web services or when any client/server call is made? In that case, do you put all the data you need (and the one you think you will need?) in one DTO bunch?
DTOs are generally used to share information between layers. Their main purpose is isolating Entities so that you can change how your information is persisted from how the information flows through the different beans and controllers in your project.
To know when I need a DTO and when not I follow these rules:
Does the method more than three parameters? Then use a DTO.
Does the method return more than a single parameter? Then use a DTO.
When passing parameters to method calls / from method results: Does each element have more than one type (for Maps you would look at the value)? Then use a Collection of DTOs.
Otherwise use String, int, Long, etc.
Also never mind reusing DTOs even if most of its fields are not used for a specific method, you won't be wasting much memory if it's properly design. On the other hand, don't worry if you need to create new DTOs that share fields with some others, it might be clearer when reviewing your code. Try to find the right balance between too many DTOs and overpopulated DTOs.
Lastly, in a MVC model, where does each one go? Can I make an entity or a vo in either layer? Where does the DTO go?
It depends on how you structure your project. The term layer is a bit open as it can refer to each of the MVC elements and to the Data/Business/Client architecture (when I used the word layer in this answer, I'm talking about the later classification).
It is a good practice to separate each layer in a different project (specially in large projects). This is a common structure I use for enterprise web applications:
ProjectNameDao: Includes database access methods and entities.
ProjectNameBo: Includes all the business logic. Shares information with the other layers by using DTOs. It is, along ProjectNameDao, the Model in a MVC model.
ProjectNameWeb: Includes views and controllers from the MVC model.
ProjectNameDto: Includes all DTOs.
ProjectNameUtils: Shared utils, normally POJOs that hold constant values or provide basic functionality like Date formatting.
This structure needs to be adapted to whatever your requirements are, of course.
With the introduction of Hibernate in my project, my code started getting really coupled, and boilerplate in many places (and it should be the other way round, right?)
I got pretty confused by a particular example. I've always considered DAO objects to be pretty generic in their nature (mostly encapsulating the basic CRUD oeprations as well as the backend storage implementation)
Unfortunately, as my entity classes started to get more complicated, I started offloading more and more logic to the DAO objects. I have a particular example:
my entity class User should have a relation called friends, which is essentially a collection of users. However, I have to map my class to a collection of UserFriendship objects instead, each of which contains a ref to the friend object, but also other specific friendship data (the date when the friendship occurred)
Now, it is easy to introduce a custom getter in the entity class, which will take the collection of UserFriendship objects and turn it into a collection of User objects instead. However, what if I need only a subset of my friends collection, say, like in paging. I cannot really do that in the entity object, because it doesn't have access to the session, right? This also applies to when I need to make a parametrized query on the relationship. The one that has the access to the session is the UserDAO. So I ended up with this
UserDAO
=> normal CRUD methods
=> getFriends(Integer offset, Integer limit);
=> a bunch of similar getters and setters responsible for managing the relationships within the User instance.
This is insane. But I cannot really do anything else. I am not aware if it is possible to declare computed properties within the entity classes, which could also be parametrized.
I could technically also wrap the DAO within the entity, and put the helper getters and setters back into the entity class, where they should be, but I am not sure whether if that is a good practice as well.
I know that the DAO should only be accessed by the controller object, and it should provide a more or less complete entity object or a set of entity objects.
I am deeply confused. More or less all of my DAO objects now couple logic that should be either in the Entity objects or in the controllers.
I am sorry if my question is a bit confusing. It is a bit hard to formulate it.
My general rules are:
in the entity classes, respect the law of Demeter: don't talk to strangers
the entity classes must not use the session
the controller/service classes must not use the session. They may navigate in the graph of entities and call DAO methods
DAO methods should be the ones using the session. Their work consists in getting, saving, merging entities and executing queries. If several queries or persistence-related actions should be executed for a single use-case, the controller/service should coordinate them, not the DAO.
This way, I can test the business logic relatively easily by mocking the DAOs, and I can test the DAOs relatively easily because they don't contain much logic. Most of the tests verify that the queries find what they're supposed to find, return them in the appropriate order, and initialize the associations that must be initialized (to avoid lazy loading exceptions in the presentation layer, where I'm using detached objects)
As I understand, Data Transfer Objects are used for different purposes, so let's bound the scope with the view layer in Java (JSF) -based web-applications (i.e. there are usually some entity-objects mapped on a DB, which can be also used in a Business-Logic layer, and some transfer objects used in a presentation layer).
So, I have some misunderstanding about how should well-designed DTOs look. Should I keep them as small as possible? Or should I try to pass with them as much information as possible and design them in such way that only some (different in different use-cases) part of the DTO fields is initialized at a time?
Should I consider using some OO principles (at least inheritance and composition) when designing DTOs or they should be as simple as only a number of primitive-type fields with their accessors?
DTOs, if at all different from the domain objects/entities, should be as big as needed - you should transfer exactly all data that you need.
DTOs in any language should be pretty light weight. Whether or not to use inheritance is a question only you could answer - it really depends on the business needs. Otherwise the DTO itself should include the basic get/set properties.
Generally these objects are pretty light weight, however it really depends on the data / properties you need. If your DTO has 1 property vs 50 properties, if you need 50 so be it. When it comes time to passing data to functions / methods the DTO saves your life from having to add all those extra parameters. You're essentially just passing one object.
DTOs should be as lightweight as possible, distinct from the business objects, and limited in scope (for example package level objects).
I say they should be separate from the business objects, contrary to Bozho's statement "if at all different from the domain objects", because a DTO will often need setters that users of the business object should not use.
I have, for example, a Person object and a PersonDTO... the DTO needs a setter for the person's name (first, last, etc.) but that is retrieved from an external data source and my application is not allowed to change it, so my business object "Person" shouldn't have a setter.
I'm in the process of designing part of my companies architecture for its Java EE web applications. I'm pretty clear on the reasons to use a façade and one or more DAOs. The problem I have is this:
There will be some logic that definitely belongs in the integration tier because it's all about keeping the data model consistent. Except the logic goes beyond simply maintaining referential integrity and other 'raw' persistence tasks which will be handled by JPA and Hibernate. I don't class this as business logic because it's separate to any business function. However, my understanding is that a DAO should only implement the logic required to access and persist objects to the data source.
My conclusion is that I need a 'business object'-like pattern which is appropriate for the integration tier. I've looked around and the closest thing I have found (yet still not quite right to my mind) is the Sun Transfer Object Assembler pattern.
Either there's a gap in my understanding of Java EE or there is a pattern out there that will fit.
maybe a mediator is what you want:
Define an object that encapsulates how a set of objects interact. Mediator promotes loose coupling by keeping objects from referring to each other explicitly, and it lets you vary their interaction independently.
then you can use a DaoMediator in order to coordinate two or more DAOs
It sounds to me like you may be missing a controller, and consequently may need the MVC pattern. The controller will look after the DAOs and present a consistent view (don't think in terms of GUIs, burt rather some client-facing interface). When modifications are made via this view, then the controller coordinates the changes to the model via the DAO. I suspect that your facade objects may be the view in this scenario.
Having said this, I wouldn't worry too much about identifying particular patterns. You often find that taking into account all your requirements and separating concerns where applicable, that you end up implementing a particular pattern and only identify it as such after the fact.
Have you considered using aggregates from Domain Driven Design?
I'm a student of DDD myself and it seems the business logic you're trying to design could be accomplished by richer POJO-like domain models. You'd have each
domain object to be responsible for its aggregate objects, and also including any logic concerning that business concept; that said, your integration layer would coordinate those rich objects but would refrain from having real logic per se (i.e several conditional logic).
Perhaps the pattern you're trying to find is actually a step into richer domain objects?
I think it's a DataMapper (or Adapter) pattern between your DAL and your Business Layer, but without a more concrete understanding i couldn't be sure.
What is driving the requirement for consistency between the DAOs? If there is some business assumption that is dictating the relationship. For example, you might have an invoice type that when it is 'Capital' then we have to make sure several other objects are in the right state or have the right set of values. This is definitely outside the realm of the data-layer.
I wouldn't try to hard to find the perfect pattern for this case. You need some sort of coordinating class though, a mediator or controller of some sort.
I've recently overheard people saying that data transfer objects (DTOs) are an anti-pattern.
Why? What are the alternatives?
Some projects have all data twice. Once as domain objects, and once as data transfer objects.
This duplication has a huge cost, so the architecture needs to get a huge benefit from this separation to be worth it.
DTOs are not an anti-pattern. When you're sending some data across the wire (say, to an web page in an Ajax call), you want to be sure that you conserve bandwidth by only sending data that the destination will use. Also, often it is convenient for the presentation layer to have the data in a slightly different format than a native business object.
I know this is a Java-oriented question, but in .NET languages anonymous types, serialization, and LINQ allow DTOs to be constructed on-the-fly, which reduces the setup and overhead of using them.
"DTO an AntiPattern in EJB 3.0" (original link currently offline) says:
The heavy weight nature of Entity
Beans in EJB specifications prior to
EJB 3.0, resulted in the usage of
design patterns like Data Transfer
Objects (DTO). DTOs became the
lightweight objects (which should have
been the entity beans themselves in
the first place), used for sending the
data across the tiers... now EJB 3.0
spec makes the Entity bean model same
as Plain old Java object (POJO). With
this new POJO model, you will no
longer need to create a DTO for each
entity or for a set of entities... If
you want to send the EJB 3.0 entities
across the tier make them just
implement java.io.Serialiazable
OO purists would say that DTO is anti-pattern because objects become data table representations instead of real domain objects.
I don't think DTOs are an anti-pattern per se, but there are antipatterns associated with the use of DTOs. Bill Dudney refers to DTO explosion as an example:
http://www.softwaresummit.com/2003/speakers/DudneyJ2EEAntiPatterns.pdf
There are also a number of abuses of DTOs mentioned here:
http://anirudhvyas.com/root/2008/04/19/abuses-of-dto-pattern-in-java-world/
They originated because of three tier systems (typically using EJB as technology) as a means to pass data between tiers. Most modern day Java systems based on frameworks such as Spring take a alternative simplified view using POJOs as domain objects (often annotated with JPA etc...) in a single tier... The use of DTOs here is unnecessary.
Some consider DTOs an anti-pattern due to their possible abuses. They're often used when they shouldn't be/don't need to be.
This article vaguely describes some abuses.
The question should not be "why", but "when".
Definitively it's anti-pattern when only result of using it is higher cost - run-time or maintenance. I worked on projects having hundreds of DTOs identical to database entity classes. Each time you wanted to add a single field you ad to add id like four times - to DTO, to entity, to conversion from DTO to domain classes or entities, the inverse conversion, ... You forgot some of the places and data got inconsistent.
It's not anti-pattern when you really need different representation of domain classes - flatter, richer, ...
Personally I start with a domain class and pass it around, with proper checks at the right places. I can annotate and/or add some "helper" classes to make mappings to database, to serialization formats like JSON or XML ... I can always split a class to two if I feel the need.
It's about your point of view - I prefer to look at a domain object as a single object playing various roles, instead of multiple objects created from each other. If the only role an object is to transport data, then it's DTO.
If you're building a distributed system, then DTOs are certainly not an anti pattern. Not everyone will develop in that sense, but if you have a (for example) Open Social app all running off JavaScript.
It will post a load of data to your API. This is then deserialized into some form of object, typically a DTO/Request object. This can then be validated to ensure the data entered is correct before being converted into a model object.
In my opinion, it's seen as an anti-pattern because it's mis-used. If you're not build a distributed system, chances are you don't need them.
DTO becomes a necessity and not an ANTI-PATTERN when you have all your domain objects load associated objects EAGERly.
If you don't make DTOs, you will have unnecessary transferred objects from your business layer to your client/web layer.
To limit overhead for this case, rather transfer DTOs.
I think the people mean it could be an anti-pattern if you implement all remote objects as DTOs. A DTO is merely just a set of attributes and if you have big objects you would always transfer all the attributes even if you do not need or use them. In the latter case prefer using a Proxy pattern.
The intention of a Data Transfer Object is to store data from different sources and then transfer it into a database (or Remote Facade) at once.
However, the DTO pattern violates the Single Responsibility Principle, since the DTO not only stores data, but also transfers it from or to the database/facade.
The need to separate data objects from business objects is not an antipattern, since it is probably required to separate the database layer anyway.
Instead of DTOs you should use the Aggregate and Repository Patterns, which separates the collection of objects (Aggregate) and the data transfer (Repository).
To transfer a group of objects you can use the Unit Of Work pattern, that holds a set of Repositories and a transaction context; in order to transfer each object in the aggregate separately within the transaction.