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.
Related
What is the right way to create DTOs from business objects?
Who should be responsible for creating them? BO/DTO itself from BO/some static factory?
Where should they reside in code if I have, f.e. some core library and a specific service API library that I need DTO for? In core library next to BO(which seems incorrect)/in specific library?
If I have encapsulated fields in my BO how do DTO grab them? (obviously in case when BO is not responsible for creating DTOs)
As an example assume that I have some Person BO like this:
class Person
{
private int age;
public bool isBigEnough => age > 10;
}
I want age to be an internal state of Person but still I need to communicate my BO to some api. Or having private field in my class that I want to send somewhere already means that it should be public?
Are there any general considerations of how to use DTOs alongside business classes with encapsulated data?
___ Update:
In addition to approaches that #Alexey Groshev mentioned I came accross another one: we separate data of our BO class into some Data class with public accessors. BO wraps this data with its api(probably using composition) and when needed it can return its state as Data class as clone. So dto converter will be able to access Domain object's state but won't be able to modify it(since it will be just a copy).
There're multiple options available, but it would be difficult to recommend anything, because I don't know the details about your project/product. Anyway I'll name a few.
You can use AutoMapper to map BOs to DTOs and vise versa. I personally dislike this approach, because it's quite difficult (but possible) to keep it under control in medium/large sized projects. People don't usually bother to configure mappings properly and just expose internal state of their objects. For example, your isBigEnough would disappear and age would become public. Another potential risk is that people can map DTOs to/from EF/Hibernate objects. You can find some articles which explain why it's considered to be a bad practice.
As you suggested, a BO can create DTO by itself, but how would you implement this approach? You can add methods or factory methods to your entities, e.g. public PersonDto ToDto(). Or you can add an interface, e.g. public interface IDtoConvertable<T> { T ToDto(); }, and choose which entity or aggregate root will implement it. Your Person class would look like this class Person : IDtoConvertable<PersonDto> {... public PersonDto ToDto() {...} }. In both cases DTO namespace/assembly must to accessible by entities which sometimes can be a problem, but usually it's not a biggie. (Make sure that DTOs cannot access entities which is much worse.)
(C#) Another option is to return a delegate which creates DTO. I decided to separate it from (2), because entity doesn't really create DTO by itself, but rather exposes a functionality which creates DTO. So, you could have something like this public Func<PersonDto> ToDto() {...}. You might want to have an interface as in (2), but you get the idea, don't you? Do I like this approach? No, because it makes code unreadable.
As you see, there are more questions than answers. I'd recommend you to make a few experiments and check what works for you (your project) and what doesn't.
I think the answer to question 5 will address the other questions too.
Are there any general considerations of how to use DTOs alongside business classes with encapsulated data?
Remember, a DTO is solely to transfer data. Do not concern yourself with implementing any kind of rules in the DTO. All it is used for is to move data from one subsystem to another (NOT between classes of the same subsystem). How that data is used in the destination system is out of your control -- although as the God programmer you inherently know how it is going to be used, DO NOT let that knowledge influence your design -- and therefore there should be no assumptions expressed as behaviour or knowledge accessors -- so, no isBigEnough.
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.
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();
}
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
I am wondering what makes sense in relation to what objects to expose through a WCF service - should I add WCF Serialization specifications to my business entities or should I implement a converter that maps my business entities to the DataContracts that I want to expose through my WCF service?
Right now I have entities on different levels: DataAccess, Business and Contract. I have converters in place that can map entities from DataAccess to Business and from Business to Contract and vice versa. Implementing and Maintaining those is time consuming and pretty tedious. What are best practices in relation to this?
If I were using an OR/M such as NHibernate or Entity Framework should I be exposing the entities from the ORM directly or should I abstract them the same way I am doing now?
In general, I think from a best practices standpoint, you should not expose the structure of your business objects as data contracts, but rather define "data contract-specific" classes and convert Business to Contract. It may require extra work, but from a separation of concerns and protection from change standpoint the extra work is probably worth it.
The Microsoft patterns & practices "Service Factory Modeling Edition" implements this, and also provides tooling to auto-generate Business <=> Contract converter classes -- it's an excellent VS add-in, and also represents Microsoft's best practices for WCF.
I typically don't expose my business/data entities across the wire since I like to adhere to the single responsibility principle (srp). To explain, the data entities were created to map to the underlying relational (db) model. So the only reason they should "change", is because of a change to the relational model, that's it.
The moment you expose such entities so they can cross the wire, then they're serving two purposes. It may seem like overkill, but it keeps things cleaner and transparent...which yields for a simpler design.
Just to add to the above answers:
The object that the webservice exposes is called the Data Transfer Object (DTO). Having a DTO to map your Business Entity object (BEO) is good because of the separation it provides between your webservice and the actual implementation/logic that lies behind the web-service.
Finally, here is how you can decorate the DTO so that when it is exposed by the WSDL the names reflect the actual objects it represent (instead of objectNameDTO or something ugly like that).
//Business Entity
class Person
{
public string Name{ get; set; }
public int Age{ get; set; }
}
//Data transfer object
[DataContract(Name="Person")] //<-- this is what makes the WSDL look nice and clean
class PersonDTO
{
[DataMember(Name = "Name", Order = 0)]
public string Name{ get; set; }
[DataMember(Name = "Age", Order = 1)]
public int Age{ get; set; }
}
Something to also consider, I agree with the separation but it usually winds up leading to "Translators" or some such code to copy the data from the DTO to the Business Entity. This is where a library like AutoMapper (http://automapper.org/) comes in REAL handy and does away with the need to write the translation layer.