With DDD you end up with either "Use-case-specific logic scattered across domain model creating logical dependency to use-cases. Unstable (frequently changing) domain model." or services with "zillions of calls to property setters and getters, low level of code re-use, entity logic scattered across services, tight coupling to domain layer"
With DCI "Use-case-bound domain behavior injected into domain object by the app"
http://www.slideshare.net/johaneltes/dci-with-groovy
Wednesday, May 30, 2012
Sunday, May 27, 2012
DCI - My Take
DCI tries to solve the problem of how to model transactions. It introduces notions such as Roles and Contexts which your domain objects adopt and interact within respectively. The problem is deciding now what to name your domain objects and to which to assign said roles? I pretty much disagree for instance that an account should be responsible for transferring money to another account; this is simply too anthropomorphic. If accounts are and should be dumb objects then why are they conferred the knowledge of how to perform money transfers?
I still like the idea of having broker objects like servant or avatar who in the user's mental model perform the act of taking money from one dumb account and placing it into another. Why should the account be smart? or possibly a "clerk" object who depending on the context plays the role of account closer, password resetter, withdrawer, depositor, issue escalater, etc.
I still like the idea of having broker objects like servant or avatar who in the user's mental model perform the act of taking money from one dumb account and placing it into another. Why should the account be smart? or possibly a "clerk" object who depending on the context plays the role of account closer, password resetter, withdrawer, depositor, issue escalater, etc.
TS/ADM vs. DM
One of the key benefits of a domain model approach is that it hides the complexity of the different components behind the core objects of the problem domain. I like to think that in a transaction script model, the locus of control is placed outside of your core objects. In a well designed domain model, the locus of control is contained within your core objects (even if big pieces of functionality are still implemented in external services).http://charliedigital.com/2009/07/29/domain-models-anemic-domain-models-and-transaction-scripts-oh-my/
Traits vs. Interfaces
Orthogonal concepts really. Interfaces are contracts, while traits code-reuse vehicles. I believe they are analogous to extension methods in C# and roles in DCI -- and possibly the delegate design pattern. In architectural terms they are complementary:
"creating traits that fulfill the capabilities required by an interface is the ideal use case - rdlowrey http://stackoverflow.com/questions/9205083/php-traits-vs-interfaces
"creating traits that fulfill the capabilities required by an interface is the ideal use case - rdlowrey http://stackoverflow.com/questions/9205083/php-traits-vs-interfaces
Saturday, May 26, 2012
Extension Methods
In my last project, I used extension method to attach Validate() methods to business objects. I justified this because the business objects where serializable data transfer objects and will be used in diffrent domains as they where general ecommerce entities such as product, customer, merchant etc. Well in diffrent domains the business rules may be diffrent as well so I encapsulated my late bound validation logic in a Validate method attahced to the base class of my data transfer objects.Athens - http://stackoverflow.com/questions/487904/what-advantages-of-extension-methods-have-you-found
Specflow
"I call this project 'specs', I didin't call this 'tests'. ... These are literally executable specifications ... and if you kind of think about that in a design sense, you usually write down the specifications of what you are going to build first; then you go ahead and build what you're going to build based on those specifications -- that in a nutshell is BDD.http://specflow.org/specflow/screencast.aspx
Testing on the other hand, if you think about science, you might come up with a theory, then you might execute some tests against that theory ... testing usually comes later; I think that's a mental block for a lot of people."
Thursday, May 24, 2012
Aggregate Roots
As we saw above, in the original creation of the Visitor entity by the Referrer, the visitor class wasn’t the aggregate root. Yet, in the user registration use case, the Visitor entity was the aggregate root. ... Aggregate roots aren’t a structural property of the domain model.http://www.udidahan.com/2009/06/29/dont-create-aggregate-roots/ [so Dahan says aggregate roots can vary by context?]
Aggregate Boundaries
Nothing outside the Aggregate boundary can hold a reference to anything inside, except to the root Entity. The root Entity can hand references to the internal Entities to other objects, but they can only use them transiently (within a single method or block).http://lostechies.com/jimmybogard/2010/02/04/strengthening-your-domain-a-primer/
Domain Services
Domain services are the coordinators, allowing higher level functionality between many different smaller parts. These would include things like OrderProcessor, ProductFinder, FundsTransferService, and so on. Since Domain Services are first-class citizens of our domain model, their names and usages should be part of the Ubiquitous Language. Meanings and responsibilities should make sense to the stakeholders or domain experts.
http://lostechies.com/jimmybogard/2008/08/21/services-in-domain-driven-design/
Abstract Factory
The standard solution if you need short-lived or dynamically created objects is to use an injected Abstract Factory.
Static vs. Abstract Factory
The key idea of static factory method is to gain control over object creation and delegate it from constructor to static method. The decision of object to be created is like in Abstract Factory made ouside the method (in common case, but not allways). While the key (!) idea of Factory Method is to delegate decision of what instance of class to create inside Factory Method. E.g. classic Singleton implementation is a special case of static factory method.Grygoriy Gonchar -http://stackoverflow.com/questions/929021/what-are-static-factory-methods-in-java
Tuesday, May 15, 2012
Invariants vs. Contextual Validation
Invariants are the rules that cannot ever be broken about an entity, aggregate or VO
Contextual validation is a check that for a particular action, the entity, aggregate or VO is valid at that point.
Monday, May 14, 2012
Information Expert
Basically, put code in the same object with the data. This sounds simple, but I continually see "data only" and "code only" objects. That is the way procedural programming did things, and it is the natural result of focusing on the process while writing code. OO programming requires a certain level of design work before coding starts, and applying the Information Expert pattern is critical to that effort.http://thinkingthroughjava.blogspot.com/2011/05/grasping-gang-of-four.html
Sunday, May 13, 2012
Transaction Script = ADM?
It would seem that your project might be suffering the side effects of an anemic domain model. As I have observed that these models tend to be used mostly with a transaction script style design, I will use these two terms interchangeably.http://charliedigital.com/2009/07/29/domain-models-anemic-domain-models-and-transaction-scripts-oh-my/
What I’ve achieved by applying the DDD patterns is the elimination of those transaction scripts and (most) services. The transaction script (e.g. struts action in a web application if you’re so inclined) is simply responsible for finding an appropriate entry-point into the domain, then telling that domain class to do some work.http://evan.bottch.com/2007/12/06/factory-and-repository-in-the-domain/
Domain Logic
[The Anemic Domain Model] [n]ecessitates a separate business layer to contain the logic otherwise located in a domain model. It also means that domain model's objects cannot guarantee their correctness at any moment, because their validation and mutation logic is placed somewhere outside (most likely in multiple places).http://en.wikipedia.org/wiki/Anemic_Domain_Model
but...
[Some are] just technical constraints, according to Dahan: “The business doesn’t care that username fields are 8 characters. Usernames have to be unique for technical reasons to be able to select customers to check details”. Rules that are not part of genuine domain logic do not have to be implemented in the domain model, suggested he, because they do not model the domain. They may be deployed to a separate tier.http://agile.dzone.com/news/biggest-mistakes-teams-make
Udi again:
Validation of string lengths, data ranges, etc is not domain logic and is best handled elsewhere (and a topic for a different post). The same goes for uniqueness.http://www.udidahan.com/2009/06/29/dont-create-aggregate-roots/
Saturday, May 12, 2012
Application or Domain?
An additional question you could ask is: if, in the future, I need to build another application on top of this domain model (e.g. a web service or a rich client), would I still need to deal with the concept of a Channel?Mark Seemann - http://stackoverflow.com/questions/1425749/anaemic-domain-models-or-where-to-put-logic
Thursday, May 10, 2012
Workflows in DDD
Pawson says of simple task assignment systems:
On another note, in a previous blog he alluded to direct manipulation. I would take his task system a step further and create a world model app where a user figure can be attached with task objects, e.g. by dropping them into a bucket the avatar carries. Object collections attached to avatars could be color coded or shaped in a way that easily recognizable. Thusly, transferring objects between entities is a lot more direct than using commands and/or context menus operating on tables.
What these two design principles explicitly disallow is the idea that upon completing Task A, the workflow engine regains control and then issues Task B, either to the same user or another: the conventional notion of workflow. Rather, these two design principles reflect the fact that real business processes reside in the heads of the staff, and that is the best place for them.http://blog.nakedobjects.org/2007/11/19/workflow-a-triumph-of-hope-over-experience/
On another note, in a previous blog he alluded to direct manipulation. I would take his task system a step further and create a world model app where a user figure can be attached with task objects, e.g. by dropping them into a bucket the avatar carries. Object collections attached to avatars could be color coded or shaped in a way that easily recognizable. Thusly, transferring objects between entities is a lot more direct than using commands and/or context menus operating on tables.
Monday, May 7, 2012
CQRS
In regular client-server development, the server is responsible for providing the client with all CRUD (create, read, update, and delete) capabilities. However, when users look at data they do not often require it to be up to date to the second (given that they often look at the same screen for several seconds to minutes at a time). As such, retrieving data from the same table as that being used for highly consistent transaction processing creates contention resulting in poor performance for all CRUD actions under higher load.http://www.udidahan.com/2008/08/11/command-query-separation-and-soa/
Querying: - Have a look to Users, what are they really interested in? - It's not searching, it's finding; - It's not refreshing, it's looking for eventsAlberto Brandolini - http://vimeo.com/16054927 - 41:10
Sunday, May 6, 2012
Aggregate Roots
The biggest rule to keep in mind is that aggregate roots are the only kind of entity to which your software may hold a reference.http://msdn.microsoft.com/en-us/magazine/dd419654.aspx
Instead of worrying too much about aggregate boundaries, we greatly reduced the relative boundaries of roots, until it was a use-case per use-case basis that determined where we drew our boundaries.http://lostechies.com/jimmybogard/2009/09/11/wither-the-repository/ - failure of ARs
Contexts vs. Modules
Contexts are subsystems (in code different assemblies) within a domain. Each context has its own ubiquitous language; this provides context for domain entities within a given subsystem (Context).
A Context is further broken down into modules which are separated by namespaces.
see http://msdn.microsoft.com/en-us/magazine/dd419654.aspx
A Context is further broken down into modules which are separated by namespaces.
see http://msdn.microsoft.com/en-us/magazine/dd419654.aspx
Entities vs. Value Objects
A value object can become an entity depending on the situation. ... If the requirement of the search functionality of your application says that, the search criteria should be saved in the database and the user can do the same search from the list of saved search criteria’s. In this scenario SearchCriteria has its own identity and thus it is an entity instead of being a value object. ...http://www.codeproject.com/Articles/339725/Domain-Driven-Design-Clear-Your-Concepts-Before-Yo
remember that Aggregate Roots may comprise one or many Entities and Value Objects
Value objects are immutable. see fig 2 example in http://msdn.microsoft.com/en-us/magazine/dd419654.aspx
Friday, May 4, 2012
Domain Entities
Main concern of entities should be keeping track of business state - that's enough of a responsibility and they shouldn't be concerned with validation. ...
[W]hether an entity is "valid" depends on its state and its context. George Polevoy points this out nicely in his answer and I share his opinion.Marijn - http://stackoverflow.com/questions/5818898/where-to-put-global-rules-validation-in-ddd
The above appears to contrast with the following advice:
Also your example seems to imply that your object can exist in an invalid state, this should be avoided, your domain object should always be in a valid state.Kdeveloper - http://programmers.stackexchange.com/questions/70734/ddd-a-rookies-unanswered-questions
Oder is both a noun and a verb. The "Order" is the object that created as a result of "Ordering". Like any good class, it has both data and behavior (and I don't mean getters and setters). The behavior is the dynamic process that goes with the data, i.e., the ordering workflow. "Order" is the controller.Doug Knesek - http://stackoverflow.com/questions/1468218/domain-driven-design-where-does-the-workflow-logic-lie
When a domain object begins to contain too many responsibilities, we start to break out those extra responsibilities into things like value objects and domain services.http://lostechies.com/jimmybogard/2010/03/30/strengthening-your-domain-the-double-dispatch-pattern/
Factories
But still the creation logic is kind of separate from the rest of the logic as it’s only needed during creation time and not during the rest of the lifecycle of an object. Thus when creation logic gets complex enough, like calling repositories, you should spinoff this separate concern to another object, a factory object.http://programmers.stackexchange.com/questions/70734/ddd-a-rookies-unanswered-questions
Wednesday, May 2, 2012
Active Record vs. DDD
http://www.udidahan.com/2008/02/15/from-crud-to-domain-driven-fluency/
With the Active Record Design Pattern we will focus on persistence as a responsibility rather than as a service.http://web.archive.org/web/20110625073754/http://davidhayden.com/blog/dave/archive/2006/06/10/2984.aspx
DDD Examples
- For example, I am working on some software right now where you basically have an estate which can have a number of sites and all I seem to be modelling is Estate.AddSite, Estate.RemoveSite etc. And the only thing I seem to be putting in my domain object is validation e.g. the Site description cannot be blank…
Would you class these as domain methods or just service layer methods?
I think you’re right in terms of this takes a whole different mind set !
- udidahan Says:
January 20th, 2010 at 2:23 pm Andrew,
I think that the issue is that the UI you’re supporting is exposing that kind of functionality to the user. DDD applies to UI design as well.
The code in the post is indeed the implementation of service layer methods.
see main article http://www.udidahan.com/2008/02/15/from-crud-to-domain-driven-fluency/
More examples:
http://www.udidahan.com/2008/02/29/how-to-create-fully-encapsulated-domain-models/
http://msdn.microsoft.com/en-us/magazine/dd419654.aspx
By Jimmy Bogart: http://vimeo.com/43598193 He demonstrates how to transform an anemic domain model to a "wicked" domain model. One of the objectives of doing DDD he says is to protect the code from developer mistakes. The way to do so is to remove operations on properties of model objects from the calling to code to the object itself and make as much object state as necessary private (encapsulation). He also demonstrates how to refactor a switch statement down to the enum equivalent in .NET which is a pattern whereby an abstract class representing the enum (and having similar functionality) contains private classes that inherit from the outer abstract class. These private classes do/return whatever was in the case blocks. The abstract class exposes instances of these classes via separate public static getter methods with names that match enum names, and so the calling code gets polymorphic behavior based on what's returned.
DDD/OO vs. Relational Model
Foreign keys are artifacts of relational data model. Object model operates
with the concept of container. So, Order contains a collection of Order Lines.
Order Line contains Product, etc.
| |||||
http://stackoverflow.com/questions/728040/ddd-related-entities-in-master-detail-relationships |
Domain Entities
Applying commands/method invocations to an entity or aggregate root can be seen as an application of a function to a data structure where the result of the function application is an identical data structure with different data and/or versionhttp://en.wikipedia.org/wiki/Domain-driven_design implies a key characteristic of entities is statefulness
Persistence Ignorance
Your questions and doubts ring an interesting alarm here, I think you went a bit too far in your interpretation of a "rich domain model". Richness doesn't go as far as implying that persistence logic must be handled by the domain objects, in other words, no, they shouldn't know how to save and delete themselves (at least not explicitely, though Hibernate actually adds some persistence logic transparently). This is often referred to as persistence ignorance.ian31 - http://stackoverflow.com/questions/4708689/ddd-where-to-put-persistence-logic-and-when-to-use-orm-mapping
I suggest that you keep the existing DAO injection system (a nice thing to have for unit testing) and leave the persistence layer as is while trying to move some business logic to your entities where it's fit. A good starting point to do that is to identify Aggregates and establish your Aggregate Roots. They'll often contain more business logic than the other entities.
However, this is not to say domain objects should contain all logic (especially not logic needed by many other objects across the application, which often belongs in Services).
Tuesday, May 1, 2012
DDD Lazy Loading
Now that our CustomerRepository can save customers as well as associated addresses in a decoupled manner we need to move onto the next problem, reconstituting our customer object with an address. As others have mentioned we may want to Lazy Load the address since there will be instances when it isn't needed.http://web.archive.org/web/20100420152400/http://steve.emxsoftware.com/Domain%20Driven%20Design/DDD%20Reconstituting%20objects%20from%20multiple%20Repositories Note! He goes on to say this is NOT the optimal solution (too much coupling)
public class Customer {
public int addressKey;
public Address Address {
get {
if(address == null) {
address = new AddressRepository().Load(addressKey);
}
return address;
}
}
Domain Model vs. BLL
Just to be clear, I like to think of a Business Model and Business Logic as two separate layers. Your business model are your POCOs (Plain old CLR objects). Your business logic layer would be responsible for performing validations, transactions, etc using both your business model and an interface to your DAL that could be wired up a number of ways (Spring, Castle, or your own home grown IoC container).
Trent - http://www.techques.com/question/1-458098/Business-Logic-Layer-and-Data-Access-layer:-circular-dependency
I'd like to remove the coupling to allow us to support different address repositories as we can with the .Save within our CustomerRepository (via RepositoryFactory). I'd also like to remove any knowledge of repositories from my domain objects. Although it isn't always possible I prefer for application code to have knowledge of repositories NOT my domain objects.http://web.archive.org/web/20100420152400/http://steve.emxsoftware.com/Domain%20Driven%20Design/DDD%20Reconstituting%20objects%20from%20multiple%20Repositories
Project Structure
Samples in links.
http://stackoverflow.com/questions/5384246/ioc-and-managing-interfaces - David comment - note: reiterates that Domain Logic library should reference nothing.
http://stackoverflow.com/questions/7742858/ioc-and-interfaces - Gregory A Beamer comment - note where "Test" type projects in subareas.
http://www.techques.com/question/1-458098/Business-Logic-Layer-and-Data-Access-layer:-circular-dependency - Craig Wilson comment - note repository implementations in separate projects
http://stackoverflow.com/questions/5384246/ioc-and-managing-interfaces - David comment - note: reiterates that Domain Logic library should reference nothing.
http://stackoverflow.com/questions/7742858/ioc-and-interfaces - Gregory A Beamer comment - note where "Test" type projects in subareas.
http://www.techques.com/question/1-458098/Business-Logic-Layer-and-Data-Access-layer:-circular-dependency - Craig Wilson comment - note repository implementations in separate projects
Layer-Specific Models
There seems to be consensus that each layer should have its own model. In addition to the core Domain Model and the ViewModel, there's also the "Persistence Model." Comment from SO:
Mark Seemann - Dependency Injection in .NET p50
- The persistance library(s) may have a different model and I may have a view model on the experience library(s). Gregory A Beamer - http://stackoverflow.com/questions/7742858/ioc-and-interfaces
Mark Seemann - Dependency Injection in .NET p50
PM is a property bag while DM is about business logic and behavior
http://www.mehdi-khalili.com/orm-anti-patterns-part-4-persistence-domain-model
Subscribe to:
Posts (Atom)
Does this sound like something that warrents DDD or am I trying to fit something in that just doesnt fit, I cant believe this, as nearly all web based systems are just reflections over data at their core and merely provide facilities for the users to perform basic crud methods on a system. Would you model the crud methods e.g. AddRegion as a domain method or just at the service level?
Sorry to be a pain, but this is one of the biggest hurdles I always have with DDD, if you can suggest any reading or articles, I would be extremely grateful (where did I put Erics book…)
January 23rd, 2010 at 9:32 pm Andrew,
That kind of behavior can be built using the Active Record pattern instead of the Domain Model pattern. As you said, it is simple data manipulation and, as such, doesn’t require it. That said, DDD is broader than the Domain Model pattern and there are many other useful elements to it that can still be applicable.