Specification pattern is a common pattern used in DDD that encapsulate business logic to respond to one question.
public interface ISpecification<T>
{
bool IsSatisfiedBy(T aSource);
}
public class CustomerHaveDiscountSpec : ISpecification<Customer>
{
bool IsSatisfiedBy(Customer aCustomer)
{
/* ... */
}
}
Which other patterns are common in Domain-Driven Design?
I recommend InfoQ's Domain Driven Design Quickly, which does a good job of distilling the (too) longer book by Eric Evans. Building upon #Pangea's answer, the objects list deserves some description:
Repository: encapsulates persistence and search - typically database
Service: stateless API entity used for aggregate root CRUD
Aggregate Root: an entity whose other child composite entities lack appropriate meaning without it - perhaps the most important aspect from an API perspective when talking about DDD
Value Object: entity whose state does not change after instantiation (e.g. Color), particularly useful in multithreaded programming because using such eliminates concurrency issues
I do not think we call this as patterns but some concepts are repository, aggregate root, value object, entity, domain services, application services. Below two links are helpful
http://dddcommunity.org/resources/ddd_terms
https://dzone.com/refcardz/getting-started-domain-driven
Related
All my entities are implementation of interfaces. Most of their properties are read-only.
My repository holds a reference to the library project where i hold all the interfaces, so technically speaking, the repository can save the aggregate root without knowing anything about it's de-facto implementation (something i believe to be a +1).
The problem here is: if most of the properties are read-only, how can I rehydrate a aggregate root without breaking OOP principles? should the repository hold a reference to the domain project and be aware of the concrete implementation of interfaces?
should the repository hold a reference to the domain project and be aware of the concrete implementation of interfaces?
As Evans describes in the Blue Book; the Repository is a role played by an implementation, to keep the application from mutating the underlying data directly. Similarly, the Aggregate Root is a role -- we don't let the application touch the actual entity, but instead just a limited part of it.
The implementation of the repository is part of the model, so it can know more about the specific entities being represented; including knowing how to extract from them a representation of state that can be handed off to your persistence component for storage.
To choose a specific context, let's pretend that we are modeling a TradeBook, and one of the interesting use cases is that of a customer placing orders.
In Java, the implementation of the Repository interface -- the bit that the application knows about, might look like
interface API.TradeBookRepository<TradeBook extends API.TradeBook> {
TradeBook getById(...);
void save(TradeBook);
}
interface API.TradeBook {
void placeOrder(...);
}
So the application knows that it has an access to a repository, but it doesn't know anything about the implementation but the promise that it
will provide something that supports placeOrder.
So the application code looks like:
API.TradeBookRepository<? extends API.TradeBook> repo = ....
API.TradeBook book = repo.getById(...);
book.placeOrder(...)
repo.save(book)
But a given repository implementation is usually coupled to a specific implementation of the book; they are paired together.
class LIFO.TradeBook implements API.TradeBook {
...
}
class LIFO.TradeBookRepository implements API.TradeBookRepository<LIFO.TradeBook> {
...
}
how can I rehydrate a aggregate root without breaking OOP principles?
To some degree, you can't. The good news is, at the boundaries, applications are not object oriented.
The thing you are putting into your durable store isn't an aggregate root; it's some representation of state. I tend to think of it as a Memento. What you really have are two functions - one converts a specific aggregate root implementation (ex: LIFO.TradeBook) to a Memento, the other converts a Memento to an aggregate root.
Key idea: you are probably going to want to change your domain model a lot more often than you are going to want to migrate the database. So the Memento needs to be designed to be stable -- in effect, the Memento is a message sent from the old domain model to the new one, so many of the lessons of message verioning apply.
Simply put, something somewhere in your application has to know about concrete implementations. If you really want to shield the repository implementation (not the contract) from knowing the concrete entities then that responsibility will simply have to fall on another collaborator (e.g. repository would delegate the rehydration to an abstract factory).
However, it's quite uncommon to have separate contracts for aggregates because you usually have a single implementation of these business concepts and there's usually no scenario where you would want to mock them in unit tests. Therefore, repository contracts and implementation are most of the time defined in terms of concrete aggregates.
I’m trying to implement domain driven design (DDD) whilst at the same time using SOLID design principles but had the following question:
If my domain entities contain only state and the behavioural methods associated with them within the ubiquitous language are placed into separate classes does this classify as either an anemic or rich domain model?
For example, instead of having this on my entity:
class Order
{
public virtual void Ship();
}
I’ve actually factored this out into a separate OO class:
class Shipper
{
public virtual void Ship(Order order);
}
From my point of view this is still inside the “model” rather than the service/application layer, therefore I believe this would still be a rich domain model.
I may however delegate the call of retrieving my order and shipping it inside the service layer as follows:
class OrderService
{
//private member construction ommitted for brevity
Repository _repository;
ShipOrder _shipper;
public void Ship(int orderId)
{
Order order = _repository.GetOrder(orderId);
_shipper.Ship(order);
}
}
The reason for NOT implementing the behavioural logic inside the domain entity is that implementing it would go against the single responsibility principle, in that the responsibility of my entity is to maintain and store state within my domain. However, my opinion on this is could be subjective.
As far as I understand, Shipper and Order are two different concepts in your domain (non-technically speaking). If that is the case, separating them is the right choice, because you should design your domain model as close to the real world as possible.
What is a shipper? Do your domain experts talk about shippers a lot? Do different shippers ship orders differently? I doubt someone working in a store would talk about a shipper. at best they would talk about the employee who ships the order.
I think separating them 'might' be fine but then shipper would be a domain service. DDD is more about lowering the communication barrier than about folling the single responsiblity principle. In DDD i doubht it would fit into your domain model for the simple reason a domain expert wouldn't talk about it. They would talking about shipping an order.
what you might do is this
class Order {
public void Ship() {
IOCContainer.Resolve<IShippingService>.ShipOrder(this);
}
}
Now you could put all the actual logic inside the shipping service (which implements the IShippingService interface). This also solves the single responsibility principle. If you read 'uncle bob's comments about the single responsiblity principle it's not so much about doing just 1 single thing, but having 1 reason to change. https://blog.8thlight.com/uncle-bob/2014/05/08/SingleReponsibilityPrinciple.html
If i implement my shipping logic like this i would expect this part of my code to have no reason to change at al, (since the change in the shipping process wouldn't be located here but in the ShippingService).
This way you could combine DDD and SOLID.
Well from the book POEAA, Martin Fowler introduced this idea of Unit of Work. It works very well if you want to have auto-commit system, in which your domain model uses Unit of work to label itself as new, dirty, removed or clean. Then you only need to call UnitofWork.commit() and all changes of models will be saved. Below is a domain model class with such methods:
public abstract class DomainModel{
protected void markNew(){
UnitOfWork.getCurrent().registerNew(this);
}
protected void markDirty(){
UnitOfWork.getCurrent().registerDirty(this);
}
protected void markRemoved(){
UnitOfWork.getCurrent().registerRemoved(this);
}
protected void markClean(){
UnitOfWork.getCurrent().registerClean(this);
}
}
With this implementation, you can mark a domain model as any save state through business logic method:
public class Message extends DomainModel{
public void updateContent(User user, string content){
// This method update message content if the the message posted time is not longer than 24 hrs, and the user has permission to update messate content.
if(!canUpdateContent(user) && timeExpired()) throw new IllegalOperationException("An error occurred, cannot update content.");
this.content = content;
markDirty();
}
}
At first glance, it looks marvelous, since you dont have to manually call insert, save and delete method on your repository/data mapper. However, I see two problems with this approach:
Tight coupling of domain model with Unit of work: This implementation of Unit of Work will make domain models dependent on UnitOfWork class. UnitOfWork has to come from somewhere, the implementation of static class/method is bad. To improve this, we need to switch to dependency injection, and pass an instance of UnitOfWork to the constructor of Domain Model. But this still couples domain model with Unit of work. Also ideally a domain model should only accept parameters for its data fields(ie. Message domain model's constructor should only accept whats relevant to message, such as title, content, dateposted, etc). If it will need to accept a parameter of UnitOfWork, it will pollute the constructor.
The domain model now becomes persistent-aware: In modern application design, especially DDD, we strive for persistent-ignorant model. The domain model shouldnt care about whether it is being persisted or not, it should not even care about whether there's persistence layer at all. By having those markNew(), markDirty(), etc methods on domain model, our domain models now have the responsibility of informing the rest of our application that it needs to be persisted. Although it does not handle the persistence logic, the model still is aware of the existence of persistence layer. I am not sure if this is a good idea, to me it seems to have violate the single responsibility principle. There's also an article talking about this:
http://blog.sapiensworks.com/post/2014/06/04/Unit-Of-Work-is-the-new-Singleton.aspx/
So what do you think? Does the original Unit of Work pattern described in Martin Fowler violate good OO design principles? If so, do you consider it an antipattern?
To be entirely accurate, there is no one "Martin Fowler's implementation of Unit of Work". In the book he distinguishes between two types of registration of a modified object into a UoW.
Caller registration where only the calling object knows about the UoW and has to mark the (callee) domain object as dirty with it. No anti pattern or bad practice here as far as I can tell.
Object registration where the domain object registers itself with the UoW. Here again there are two options :
For this scheme to work the Unit of Work needs either to be passed to
the object or to be in a well-known place. Passing the Unit of Work
around is tedious but usually no problem to have it present in some
kind of session object.
The code sample is using UnitOfWork.GetCurrent() which is closer to the latter option and admittedly widely considered an anti-pattern today because of the tightly coupled, implicit dependency (Service Locator style).
However, if the first option was chosen, i.e. passing the UoW over to the domain object, and let's assume a Unit of Work abstraction, would it be bad practice ? From a dependency management perspective, clearly not.
Now remains the persistence ignorance aspect. Can we say about an object which can signal another object it's just been edited/created/removed that it is persistence-aware ? Highly debatable.
In comparison, if we look at more recent domain object implementations out there, for instance ones in Event Sourcing, we can see that aggregates can be responsible for keeping a list of their own uncommitted changes which is more or less the same idea. Does this violate persistence ignorance ? I don't think so.
Bottom line : the specific code Fowler chose to illustrate one of many UoW possibilities would clearly be considered bad practice now, but much more so with regard to problem #1 you pointed out and not really problem #2. And this doesn't disqualify other implementations he writes about, nor the whole UoW pattern whose change-tracking mechanics are anyway most of the time hidden away in third party library magic (read: ORM) nowadays and not hardcoded as in the book's example.
From a DDD perspective, this is something you shouldn't do.
DDD contains the following rule:
An application service should only modify one aggregate per transaction.
If you follow this rule, it's clear which aggregate changed during an app service operation. This aggregate then in turn needs to be passed to a repository for saving to the DB:
repository.update(theAggregate);
No other call is required. This defeats the gain from the pattern in the form you describe it.
On the other hand, the pattern you describe introduces a dependency from the domain to the persistence mechanism (depending on the design either a real dependency or just a conceptual dependency). Now this is something you should avoid, because it increases the complexity of your model a lot (not only internally, also for clients).
As a result, you shouldn't use the pattern in this form together with DDD.
Outside of DDD
Having that said, I think the pattern is one of many solutions to a certain problem. That solution has pros and cons, some of which you describe in the question. In some situations, the pattern may be the best trade-off, so
No, this is not an anti-pattern.
I don't think the model should not have a dependency on the UoW. It would be more like a repository that would depend on the UoW and, in turn, the repository would depend on the model.
If your repositories only depend on an abstract UoW, then the only piece of the puzzle that knows about the persistence technology is the concrete UoW.
The only classes I tend to allow the model to depend on are other pieces of the model: domain services, factories, etc.
How to make entities lazy load its relationships?
For example: Post and Comment models, where a Post can have 0 or more Comments. How to make the getComments() method on Post entity lazy load its Comments?
My first think, is to have an CommentRepository injected into my Post entity, how is this bad? Since Entities and Repositories are part of may domain, why can't they have a two way knowledge about each other?
Thank you
UPDATE
I know there are many excellent industry standard ORMs that perform lazy loading for the main languages out there, but I don't want to rely on its magics. I'm looking for a ORM/DBAL agnostic solution to make sure of the application's low coupling.
Aggregates represent a consistency boundary so there should never be a need to lazy-load related data as the aggregate as a whole should always be consistent. All objects that belong to an aggregate have no need to exist on their own. If you do have an object that has it's own life-cycle then it needs to be removed from the aggregate.
When you do find that you need to do this you may want to rethink your design. It may be that you are using your object model to query. You should rather have a light-weight query model that can perform this function.
Injecting repositories or services into entities is generally not the best idea. A double-dispatch mechanism should be preferred.
But in your case I would still try to not lazy-load.
Consider using a proxy that subclasses Post, overrides the getComments() method. Inject the proxy with the CommentRepository and access it in the overridden getComment() method.
This is how an ORM would typically do it. It keeps your domain classes clean as only the proxy is dependent on a data access mechanism.
At first, you should separate domain concept from details of realization. Agreagate pattern is about how to organize your domain and lazy-loading is an implementation detail.
Also, I disagree with #Eben Roux about inconsistency of agreates. Lazy loading contradicts nothing in my opinion. I express why.
Lazy loading itself
To understand how lazy loading can be implemented you may refer to Martin Fowler's PoEAAA pattern 'Lazy loading'. For me, proxy pattern is the best solution.
Also, it's important that most nowadays ORMs supports lazy loading, BUT for data model (not domain model).
It is a good practice to separate data model and domain model and use repostiories to hide this transformation:
Separated domain and data models
In this case objects of domain model are constructed inside repositories those hide ORM context. Required data object and all associations are loaded by ORM, than transformation to domain model is performed, and finally, constructed domain object returned.
The question is how to load some associations not during creation of domain object, but during it's lifetime. You can use Repoisotry inside entity and I see nothing wrong with it. It will looks like:
public class Post {
private ICommentsRepository _commentsRepository;
private IList<Comments> _comments;
//necessary to perform lazy loading (repository always wroks with ids)
private IList<int> _commentIds;
//realize lazy loading
...
}
there are problems:
Your model now becomes not clear. It contains 'techincal' information like _commentIds.
As soon as you want to define ICommentsRepository you claim the Comment to be aggregate root. If we introduce agregate pattern into domain model, repositories should be creaed just for agregate roots. Thus it means that Comment and Post are different agregate roots. And possible that it is not what you want.
There is better solution:
public interface ICommentList {
...
}
public class CommentList : ICommentList {
...
}
public class CommentListProxy : ICommentList {
private CommentList _realCommentList;
private IList<int> _commentIds;
//realize lazy loading here using ORMs capabilities!
//don't use repository here!
}
public class Post {
private ICommentList _commentList;
...
}
Post repository will initaize _commentList field with proxy object. Also, it is necessary to say:
CommentListProxy relates to data model layer, not to domain model. It uses ORMs capabilities to implement lazy loading
and thus doesn't use repositories, and thus you may consider CommentList as a part of the Post agregate.
The only possible disadvantage of this approach is in implicit database querying when operating with domain objects. This must be clear for users of the Post class.
Smart ORMs
Finally there are kind of ORMs which allows you to use same model for both domain and data. It realizes lazy-loading for domain model in a same way as for data model. Take a look at DataObjects.Net. For some cases it is a good solution.
I've been confused by what I've been reading during my research on the repository pattern. I'm wondering if folks are (incorrectly?) using that word when they simply mean a data access layer.
Since "repository" is not found in the index of Design Patterns (GoF), I've turned to Patterns of Enterprise Application Architecture (Fowler). Fowler seems pretty clear (page 323) when he states that clients create a criteria object and pass it to the repository to get the results. It looks something like this:
public class Person
{
public List<Person> Dependents()
{
Repository repository = Registry.personRepository();
Criteria criteria = new Criteria();
criteria.equal(Person.BENEFACTOR, this);
return repository.matching(criteria);
}
}
Is the criteria object what makes the repository a repository? If not, what does? If abstracting the persistence mechanism (and therefore constructing queries) is the goal, in what way does the repository differ from a simpe DAL/ORM call like this:
public class PersonLogic
{
public List<Person> GetDependents()
{
IPersonData personData = DependencyContainer.Resolve<IPersonData>();
return personData.GetDependents();
}
}
To me, the difference looks like this:
* With the repository pattern, the client constructs different criteria objects and calls the Matching() method on it.
* With the simple DAL, clients just call different methods based on what they want.
Is there more to it than this? Are programmers mistakenly using the term "repository" when they really mean DAL?
EDIT
David Osborne sent this link to Persistence Patterns. It states:
Basically, the Repository pattern just means putting a façade over
your persistence system so that you can shield the rest of your
application code from having to know how persistence works.
That's really what a data access layer is. It really appears to me that a repository and a DAL are the same thing, and maybe a "true" repository uses the criteria object.
Take a look at the "Using the IQueryable interface" section and beyond at Extending and Enhancing the Orders and Registrations Bounded Context. It provides an insightful and balanced discussion of DAO/Repository implementations.
As subsequently highlighted by Bob Horn, the Persistence Patterns articles summarises that:
Basically, the Repository pattern just means putting a façade over your persistence system so that you can shield the rest of your application code from having to know how persistence works.
In general I agree with author's statements, but I'd like to add some details
Difference between Repository and DAL/ORM that first not only abstracts the persistence mechanism, but also provides collection-like interface for accessing domain objects … and isolates domain objects from details of the database access code:
Differences
For external layers, such as Business Logic:
Helps to avoid leaky abstraction. External layers depend on abstraction of Repository, rather than a specific implementation of DAL/ORM. Thus you could avoid all infrastructure and logical dependencies while working with Repository.
operates with domain objects, rather then a instances of POJO/POCO/DTO
CRUD operations applied to collection-like interface provided by Repository, rather then specific DAL/ORM methods. For example .net: working with collection that implements IEnumerable, rather then entity-framework context or nhibernate session
Similarities
Repository contains DAL/ORM underneath and serves same purpose