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.
Related
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.
Quite a mouth-full of a question but its a OO principle I've struggling with. Lets say i have an e-commerce app and there is the concept of payment method, examples could be CreditCard, Paypal, Apple pay etc. The user has a choice of which payment method to select so i need to present them all in a list on the screen and depending on the selection this will be used to drive a UI, presenting different text/images/interactions as well as will be serialised slightly differently into a Payment request over the wire.
Here is some code:
public class PaypalPayment : PaymentMethod {
public string Token;
public string String;
}
public class CreditCardPayment : PaymentMethod {
public Address Address;
public CreditCard CreditCard;
}
interface PaymentMethod {
}
public class Booking {
public PaymentMethod PaymentMethod; //generic object
//or
public PaypalPayment PaypalPayment;
public CreditCardPayment CreditCardPayment;
}
So in my booking class i can either have a generic payment object referred to by the interface but i cant get to the underlying type without casting which sucks, as in reality them don't share any common properties doman-wise. Alternatively i have multiple properties which feels bad in a different way. The user can only select one payment method so the others will have to null or some kind of null object, i would have to either query an enum or ask each payment method if it is null. Also my payment method select screen is a bit more cumbersome as i cant just iterate on a generic type i have to explicitly build up the list.
In theory i could add some methods to the PaymentMethod interface, such as Serialise() or some UI presentation methods which all the payment methods have in common but then i would have to implement them in my model object which i don't want to do in my model layer.
Overall i dont have a clean solution for this in your typical object orientated language. I wrote this in c# but this could apply to any OO language.
Data seems to have been segregated away from logic in your design. As a consequence, Booking probably has to indulge in Inappropriate Intimacy with its Payment in order for the behavior to take place, hence the casting problem.
An idiomatic OO implementation would 1/ define a clear responsibility and 2/ encapsulate operations and data for it in the same class. Then you can have an abstraction on top of a family of these classes so that their behavior can be called uniformly by consumer code.
The Strategy aka Policy pattern might be a good choice for payment.
UI wise, it may be better to avoid using abstractions and have different UIs altogether for different payment methods. Or, you could have an abstract UI payment model whose concrete implementations know how to render themselves.
To have an interface and can't get to the underlying type is exactly what abstraction and loose coppling is striving for. This should not suck but should be desirable.
To get all possible instances to choose from, you could use a repository that returns a collection of all your payment methods.
To implement this repository you could use your favored ORM and load them from the database, use your favored IoC/DI Container and let it create all implementors of your interface, or hard code the creation. Whatever suits you needs and the needs of the project. If you use an interface for the repository as well, you can later swap the implementation.
I am trying to get a firm understanding of DDD and having read Eric Evans book on Domain Driven Design and blogs from Julie Lerman they describe:
Anemic Domain Model as a model with classes focused on state management. Good for CRUD.
Entity as a mutable class with an identity used for tracking and persistence.
Surely both are used for the same purpose or I have completely got the wrong end of the stick? What is the difference between the two? I have read that an anemic domain model is often used to represent a database schema, but isn't the same for an entity too?
For example, a table called Customer which has:
CustomerId int
Forename varchar(50)
Surname varchar(50)
IsActive bit
From my understanding an anemic domain model to represent this would look like:
public class Customer
{
public int CustomerId { get; set; }
public string Forename { get; set; }
public string Surname { get; set; }
}
Past experiences for me suggest that an entity would also be represented in this fashion with a series of getter and setter properties, a la Entity Framework? Both concepts (entity and an anemic domain model) are mutable?
Thanks, DS.
A DDD Customer entity might have Customer::changeName(Forename,Surname)...;
changeName would only be triggered if the customer is actually changing their name. You would then embed whatever business logic is necessary for dealing with a new name. Perhaps there are pending orders with the old name. Maybe you want to update them to the new name. Maybe not. Lot's of possibilities.
For me at least the basic difference between a anemic domain object and a DDD entity is that the entity is going to actually do something more than just update properties.
[ I have read that an anemic domain model is often used to represent a
database schema, ] but isn't the same for an entity too?
Maybe you should re-read Evans' book ;) A DDD entity is one way of implementing the Rich Domain Model approach. An Entity is rich in that it captures domain actions that are referenced in the Ubiquitous Language of the application. These actions encode real-life events that can happen in a business domain, as opposed to atomic, disembodied modifications of data slots. For example, you could have an Order.ApplyDiscountVoucher(...) method that checks voucher validity and recalculates order total, as opposed to just exposing an Order.Total property and leaving it up to an external script to check the voucher and update the total.
Also encapsulated in an Entity is the responsibility of enforcing invariants, which can be applied at Entity creation or, for Entities that are Aggregate Roots, each time someone tries to change the Aggregate. An anemic model wouldn't have these business rules built in, they would be tackled in external procedures.
Whether entities, other domain objects or anemic objects should be mutable is a completely orthogonal issue to this.
I just started learning OOP and I'm finding it really hard to decide where functionality belongs. Let's use a down vote in SO for our example:
When we cast one, the following must happen in a transaction:
Decrement the voter's rep and downVotes count.
Decrement the recipient's rep.
Decrement the post score.
So...
How do we determine which action belongs to which object?
Where would such functionality live? In the DAO layer, services layer, or the actual objects themselves?
It becomes increasingly tricky when objects interact with each other, such as in my example. It's often hard to decide what function belongs to what object and so on...
Take a look at SOLID principles of OO design, Coupling & Cohesion.
OO can be used in many places, it is not limited to e.g. your Business Layer. You can write your Javascript object-oriented.
I'd model your example SO domain similar to this (in C#). This is idealistic OO code, and in real world some compromises would be made, such as making fields public for my ORM. What I am trying to show - each object is responsible for its data, noone else can change it directly; they must ask that object to do something, by calling one of the public methods.
public class User
{
private int _reputation;
private int _downvotes;
public void Downvote(Post post)
{
DecreaseReputation();
IncrementDownvotes();
post.Downvote();
}
public void RegisterDownvote()
{
DecreaseReputation();
}
private void DecreaseReputation()
{
_reputation--;
}
private void IncrementDownvotes()
{
_downvotes++;
}
}
public class Post
{
private int _score;
private User _poster;
public void Downvote()
{
DecreaseScore();
_poster.RegisterDownvote();
}
private void DecreaseScore()
{
_score--;
}
}
This is not an easy question to answer and sounds more like a design-pattern question than an OOP question per se. In the case of SO (I am making an assumption based on assumed design patterns for their site), all the "layers" of the design-pattern are involved in what you are calling a "transaction" (not a DB term I assume the way you are using it). The UI layer or View accepts the "down vote" and makes a what appears to be an ajax request most likely to a layer that handles business rules, which determines what actually happens when a "down vote" is cast against a user. At that point, the business layer makes requests of the data layer to update a database somewhere to update the user's score, reputation, etc. This also may be performed a little bit differently using web services, who knows what's under the hood here at SO. As far as OOP; I am sure there is a lot of OOP under the hood, everywhere, in all the layers, scripting and other languages perhaps, but I would imagine that in the case of your example, SO is not passing around a "User" class object when a vote is cast; there is no need to.
Here is the very popular MVC design pattern for example: http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller
Q1.
In my university studies of object-oriented modelling and design they recommend thinking about what an object can do for its method, and what its responsibilities are for its attributes. All attempts at clarification have resulted in further confusion.
This tends to generate a class diagram with actors who have all the actions, and inner classes which only hold data.
This doesn't seem correct. Is there another way of thinking about how to model the objects?
Q2. Also, the course seems to emphasize modelling the objects after their real-world counterparts but it doesn't necessarily make sense in the domain model. IE. In a medical practice, they have Patient: CreateAppointment(), CancelAppointment() but that is not how it would be implemented (you would modify a the appointment collection instead). Is there another way of thinking about this?
Example Q1
Secretary: RecordAppointment(), RecordAppointmentCancellation()
Appointment: time, date,... (no methods)
Example Q2
Doctor: SeePatient()
While SeePatient is a use-case, it does not make sense for a method on the actual class. How do you think about this?
Unfortunately, the roadblock you've hit is all too typical in academia. Academic projects tend to start with video rental stores, libraries or student registration systems (yours is a variance of this with a doctor's office) and then inheritance is taught with animals. The guideline you've provided is also very typical
they recommend thinking about what an object can do for its method, and what its responsibilities are for its attributes
In fact when beginners ask I usually explain an object's property's are the things it knows about itself and its methods are the things it knows how to do. Which is really just another way of saying exactly what you have there. As you've discovered this way of thinking quickly breaks down when you start discussing more tangible systems and not just examples.
For instance the guideline works pretty well with this object:
public class Tree
{
public int Height { get; set; }
public void Grow(int byHowMuch)
{
Height += byHowMuch;
}
}
While this certainly fits the bill your right to think that it doesn't "feel" right:
public class Secretary
{
public void MakeAppoinment(Patient patient)
{
//make the appointment
}
}
So what's the solution? It's a matter of taking what you are being taught and applying it. Learning and understanding design patterns will help a lot with developing systems which are more functional than a tree that knows how to grow.
Recommended reading:
Design Patterns: Elements of Reusable Object-Oriented Software (also known as the Gang of Four or GoF)
Head First Design Patterns
Head First Object-Oriented Analysis and Design
To solve the issue you're been presented I would probably use a combination of inherited person classes and interfaces, which would perform their actions through a series of service classes. Essentially a secretary, doctor, and patient would all inherit from person and each of these classes could be passed to accompanying service classes. The service classes may or may not do things like SeePatient(). Please don't take this example to mean that person classes wouldn't have methods.
Stack Overflow has more than a few related questions which may be of use:
Is Single Responsibility Principle a rule of OOP?
Are there any rules for OOP?
why is OOP hard for me?
Additionally, it would be good to check out:
Single responsibility principle
Don't repeat yourself
PrinciplesOfOod
Finally, there isn't a single definition of what makes an application object oriented. How you apply patterns, principles etc. will define your program. The fact that you are asking yourself these questions shows that you are on the right track.
Q1
Is it possible responsibilities of your objects should be interpreted as authorization or contract requirements, as in what actions they should take? So, to take a medical example from your Q2, an object with a Scheduler role (think C#/Java interface, or Obj-C protocol) has attributes around CanEditAppointments or EditsAppointments.
Q2
From a use case perspective, a patient may be able to create an appointment, and so you might implement a Patient in your object model with a method to CreateAppointment(). But, in terms of encapsulation, you would likely instantiate an Appointment object in CreateAppointment(), and then call methods or set properties on the Appointment object to set its time, date, patient, physician, etc.
And because the Appointment collection is likely to be permanent storage like a database, it would likely be the Appointment object's responsibility to add itself to the collection (Appointment.Schedule() goes through your data access layer to save itself to the database).
That also ties back to your Q1, in that the Appointment object's responsibility is to save itself, so it might implement an ISaveAppointment interface that requires fields and methods to carry it out. It also is the Appointment's responsibility to have a date, and time, and patient, etc., before being saved, and so the ISaveAppointment interface should require they exist, and Appointment.Schedule() should validate the values are correct or have been previously validated.
You are right that in many cases there are higher order things which more naturally contain behaviour, like the system, or the user.
You can model this behaviour in classes as static methods which operate on the data model. It isn't OO, but it's fine. You can group related methods together into such classes, and soon you have the notion of "services", as in service oriented programming.
In Java there are specifications and standards for creating such classes, namely the stateless session bean in EJB. The Spring Framework has similar notions with the stereotype "Service" which can be applied to classes to tag them as being facades for business logic.
A service is then a component which encapsulates a certain functionality or behaviour in the system. It operates on a given object model (either its own internal one, or the more general business object model from the system). If you take your use cases and create services which relate directly to them, you can write very maintainable software.
The DCI Architecture is a formalisation of this and an attempt to do the same, but at the same time trying to stay true to object orientation, by adding behaviour to objects as they need it.
I still experience the confusion: "am I telling you to do something else" or "am I doing something someone else asked of me"?
Perhaps all you have to do is play Barbie's, or G.I. Joe's to understand object interaction and where responsibilities go. G.I. Joe got wounded (or Barbie broke a nail) so he calls the Dr's office. "Hey doc, this is Joe, I need an appointment." So you, the kid, tell Barbie to go to the doctor, who needs to know the doc to call and how to call - a reference and public MakeAppointment() method. The Dr. office needs to put the appointment on the books - it's own BookAppointment() method that is the office's procedure for handling appointment requests.
public abstract GenderAppropriateDolly {
protected DrOffice Drkilldare;
public override MakeAppointment() {throw new NotImplementedException();}
}
public class GIJoe : GenderAppropriateDolly {
DrKilldare = new DrOffice();
List<Appointment> myAppointments = new List<Appointment>;
public void MakeAppointment () {
myAppointments.Add(DrKilldare.BookAppointment(this));
}
}
public class DrOffice {
List<Appointment> officeAppointments = new List<Appointments>;
public Appointment BookAppointment(GenderAppropriateDolly forWhom) {
Appointment newappt = new Appointment(formWhom);
this.Appointments.Add(newappt);
return newappt;
}
}
public class Kid {
GenderAppropriateDolly myRoleModel = new GIJoe();
// Joe got wounded so ...
myRoleModel.MakeAppointment();
}