Can I use the same aggregate class as a member in other classes?
And if yes would the class that contains the aggregate enforce access etc on that?
Let say you have a User class. Then a class named LogBook and at last a class named Log/Post (something down that alley). The LogBook would be an aggregate root for the Log/Post class and the User would be the overall aggregate in my example. Now, would the User class contain methods for adding log-posts etc? You would make one method in the User class that invokes LogBook class which has a method that does all the logic for actually adding a log.
Or, is a aggregate ALWAYS on top of the hierachy? No nesting.
Here is a nice definition of an Aggregate:
Definition: A cluster of associated objects that are treated as a unit
for the purpose of data changes. External references are restricted to
one member of the Aggregate, designated as the root. A set of
consistency rules applies within the Aggregate's boundaries. Problem:
It is difficult to guarantee the consistency of changes to objects in
a model with complex associations. Invariants need to be maintained
that apply to closely related groups of objects, not just discrete
objects. Yet cautious locking schemes cause multiple users to
interfere pointlessly with each other and make a system unusable.
[DDD, p. 126] Solution: Cluster the Entities and Value Objects into
Aggregates and define boundaries around each. Choose one Entity to be
the root of each Aggregate, and control all access to the objects
inside the boundary through the root. Allow external objects to hold
references to root only. Transient references to the internal members
can be passed out for use within a single operation only. Because the
root controls access, it cannot be blindsided by changes to the
internals. This arrangemens makes it practical to enforce all
invariants for objects in the Aggregate and for the Aggregate as a
whole in any state change. [DDD, p. 129]
I don't think you want the User class reaching into the LogBook's aggregated objects without going through the LogBook class. However, accessing the LogBook from User seems OK.
I think the internals of an aggregate are allowed to hold references to the root of other aggregates. But each aggregate is responsible for enforcing its own boundaries. There is nothing stopping other objects from accessing the "referenced" aggregate completely outside of the first one - i.e. I don't think that nesting or ownership is implied just because one aggregate references another.
In your example, it seems like LogBook would fit better as an aggregate, controlling access to posts. Trying to shoehorn this into a larger User aggregate seems to be an awkward factoring of responsibilities.
Related
I currently have two aggregate roots - Customer and AddressBook. Both have some invariants that need to be protected. Customer has reference to AddressBook and I am not sure whether that is the correct way to model my domain because one cannot live without the other and since domain objects should be created using factories I feel like I should not allow creation of Customer without AddressBook and vice versa but obviously one needs to be created before the other. Hope it makes sense.
How should I address my problem?
Other question would be: can we create multiple aggregate roots in a single transaction? I've red that it should not be done in case of update.
I currently have two aggregate roots - Customer and AddressBook. Both have some invariants that need to be protected. Customer has reference to AddressBook and I am not sure whether that is the correct way to model my domain because one cannot live without the other
If they really don't make sense without the other, you may want to review the design to see if they are really part of the same consistency boundary.
Can we create multiple aggregate roots in a single transaction?
Technically, yes. It may not be a good idea.
When all of the logically distinct aggregates are stored together, then creating them in a single transaction is straightforward.
But that also introduces a constraint: that those aggregates need to be stored "together". If all of your aggregates are in the same relational database, an all or nothing transaction is not going to be a problem. On the other hand, if each aggregate is persisted into a document store, then you need a store that allows you to insert multiple documents in the same write.
And if your aggregates should happen to be stored in different document stores, then coordinating the writes becomes even more difficult.
I would like to create closely associated AddressBook with him.... Maybe a domain event would be a more suitable option?
Perhaps; using a domain event to signal a handler to invoke another transaction is a common pattern for automating work. See Evolving Business Processes a la Lokad for a good introduction to process managers.
In all the enterprise/web application i have worked upon, i see Business/service objects(classes containing business logic) are made singleton.
My question is what is the advantage we get by making them singleton ? I can think of only one reason i.e. Service objects are needed again and again and consists of several other dependencies . So it may be bit costly(Time wise) to create these objects again and again. Is that correct ?
Yes! Thoses objects innitialization are expensive! So its better to create just one instance for all the application lifecycle!
Each and every object creation involves some cost in heap memory and we don't create multiple objects for the classes which does NOT hold any state (i.e., they are stateless)
Services, Controllers and DAOs does NOT carry/hold any state (data),
so we implement Singleton for these classes.
Where as Form Beans/Command Classes/DTO/VO objects hold data and we
create one per each request (they are NOT singletons).
What is the advantage we get by making them singleton ?
Saving memory, otherwise soon, we might get into "OutOfMemoryException" depending on configured heap size.
I can think of only one reason i.e. Service objects are needed again and again and consists of several other dependencies . So it may be bit costly(Time wise) to create these objects again and again. Is that correct ?
No, It is NOT because of dependencies, it is because they DO NOT contain any state (data) and they are costly in terms of memory & time, if we create one object per each request.
In the enterprise/web applications, if you are implementing singleton for a class (such as service/controller/DAO/etc..), then the class MUST be thread-safe.
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.
For example, when writing JPA or Hibernate code, I might want to create a descendant of a domain class, say Account. The descended version represents the a form a show the user. The form only has about half the fields that are on Account. So the object I use to hold the form value should not change the other fields.
Is using inheritance to change annotations considered bad? Assuming it is not, are there any good short hands or design patterns for doing it better or more effectively?
I'd say that the case you describe here (at least how I understood it) would not be a good candidate for creating subclasses.
Basically you want to restrict the form to change only some fields/associations of an entity, right? I further assume that you don't trust the developer of the form that only the fields that should be editable are changed, hence the requirement to restrict that.
In that case, one option might be to use the DTO pattern (data transfer object): create a DTO for the form data and let the user fill its fields. Then pass the DTO to a service which updates the entity accordingly. This way you have control of which fields are editable and how the update is performed.
Another way might be to create a wrapper for the entity that throws exceptions when a setter for an uneditable field is invoked. However, that would be a runtime solution and I'd prefer the DTO approach here.
Edit:
some reasons why inheritance might prove problematic in this case:
The subclasses don't represent entities, however, you'd still have to represent the subclasses on the database (either through discriminators or additional tables)
An entity that is created by that form would always have the subclass and thus would not be editable in other places (unless you mess with the database etc.)
Entities are data containers and should not depend on the presentation. Hence having a special entity (subclass) for one UI usecase (the form in your case) would violate the single responsibility principle and abstraction between model/data and view/presentation layer.
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.