Showing posts with label Domain-Driven Design. Show all posts
Showing posts with label Domain-Driven Design. Show all posts

Wednesday, 5 June 2013

DDD Note: Domain

Domain is a sphere of knowledge or activity. For instance, you go to your favourite superstore to buy some products. Superstore buys these products from different sources and sells them to its customer. This superstore has its own unique business knowledge and way of doing things. This understanding and its methods for carrying out its activities or operations is its Domain. If this superstore requests you to develop a software for them, then you will be working in its domain.

It is rare to find a business that has only one functionality. There are different functions that make a business successful. It is always good to think about each of those business functions separately as a Subdomain. So a domain consists of multiple subdomains. In our superstore example, we can say that it has four subdomains: Product Catelog, Orders, Invoicing, and Shipping.

Some subdomains can be labeled as core domains. A Core Domain is a part of the business domain that is most important. The success of the business mainly depends on it. It deserves most of your attention and resources.

There are two other types of subdomains: Supporting Subdomain and Generic Subdomain. In many occasions you will find that there are services created or acquired to support the business. If it models some aspect of the business that is essential, yet not Core, it is a Supporting Subdomain. Supporting subdomains provide specialized functionality, whereas Generic Subdomain captures those activities that are not special but are required for the overall business solution.

Remember Supporting and Generic subdomains are not unimportant and they also deserve attention from you. But there is no need for the business to excel in these areas. It is the Core Domain that will provide distinct advantages to the business, hence it requires excellence in implementation.


References:
  1. Domain-Driven Design - By Eric Evans
  2. Implementing Domain-Driven Design - By Vaughn Vernon

Saturday, 15 September 2012

Entities, Value Objects and Services

In chapter five A Model Expressed in Software of Domain-Driven Design, Eric Evans wrote about ENTITIES, VALUE OBJECTS and SERVICES. These are three important patterns of DDD. They help us to capture important concepts of the domain. By classifying the objects in this way we can make objects less ambiguous. In this post I write down my understanding about this topic.

So what is an ENTITY?

ENTITY = IDENTITY + CONTINUITY

ENTITY is an object that has distinct identity and also has continuity. This type of object is not fundamentally defined by its attributes. For example: two customers can have same name, age or even living in same address but they must have unique identifier (say, customer number) within the system.



ENTITY has a life cycle that can change its form and content over the time but a thread of continuity must be maintained. Here identity plays an important role because ENTITY can be tracked effectively with the help of it.



Care must be taken when generating identity for an ENTITY. Identity must be guaranteed to be unique within the system no matter how the system is developed, even whether it is distributed or not. Once generated, it must not be changed. Sometimes single data attribute (guaranteed to be unique) can be identity of an entity. For example: order number, transaction number, account number, customer number etc. Sometimes you need a combination of data attributes to define an identity. For example: daily newspapers might be identified by the name of the newspaper, the city, and the date of publication.

What about VALUE OBJECTS?

VALUE OBJECT does not have a conceptual identity but it represents a descriptive aspect of the domain.For example: A customer may be modelled as an ENTITY with an identity, but his phone number is a VALUE OBJECT.

VALUE OBJECTS help us to design and code in a better way:
  • They make implicit concepts explicit.
  • They help to write a clear service api.
  • They take the responsibility of data validation and error handling.
  • They help us to write a well testable and maintainable code.
Take the example of a phone number. We can declare it's type as string in customer class.

public class customer {  
  ...... 
  private string phoneNumber;
  ........ 
}

But if you think carefully, declaring phoneNumber as a string does not say much about it. Here the phoneNumber is implicit. It may introduce bugs, make you to write awkward and duplicate code. When you make it explicit, things become more clear:

public class customer {  
  ...... 
  private PhoneNumber phoneNumber;
  ........ 
}

It also opens option to add different behaviors to PhoneNumber. You can add data validation and error handing to this object. Here is the sample code of PhoneNumber [2]:

public class PhoneNumber {

  private final String number;
  
  public PhoneNumber(String number) {
     if(!isValid(number))
    throw ...
     this.number = number;
  }
  
  public String getNumber() {
    return number;
  }
  
  static public boolean isValid(String number) {
    return number.matches("[0-9]*");
  }
  
  public String getAreaCode() {
    String prefix = null;
    for (int i=0; i< number.length(); i++) {
 String begin = number.subString(0,i);
        if(isAreaCode(begin)) {
    prefix = begin;
    break;
        }
    return prefix;
  }

  private boolean isAreaCode(String prefix) { ... }
}
If you noticed carefully, you will find that we have put computational complexity in this object rather than putting it in service layer. So the service layer has less burden. Code duplication is reduced. Less code means less bug. Now you can write a set of junit testcases for this object.

Lets see how VALUE OBJECTS help us to write clear service api. For example: we have a api that takes name, age, address and phone number to add a customer:

void addCustomer(String, Int, String, String);

Is the above api clear to you? You can see String and Int all over, nothing meaningful. How about writing this way:

void addCustomer(Name, Age, Address, PhoneNumber);

Now the api is readable. Even a non technical person can understand the above method signature.One thing we need to remember - VALUE OBJECTS should be immutable. For example:

Money money1 = new Money("EUR", 30);
Money money2 = new Money("EUR", 40);
Money money3 = money1.add(money2);

When you add money2 to money1, you are not altering money1, instead returning a new Money object (assigned to money3) which represents the two amounts of Money added together. Ensuring immutability of value object is important if you want to share it safely. It cannot be changed except by full replacement.

Services

A SERVICE is a standalone domain operation that you cannot fit in an ENTITY or VALUE OBJECT. It is defined purely in terms of what it can do for a client.

Evans mentioned in his book that a good SERVICE should have three characteristics:
  • The operation relates to a domain concept that is not a natural part of an ENTITY or VALUE OBJECT
  • The interface is defined in terms of other elements of the domain model
  • The operation is stateless

SERVICES can be partitioned based on layer:
  • APPLICATION SERVICES sit above the domain services, handle cross cutting concern such as transaction, security. They also talk to the presentation layer to get the input or send the output back.
  • DOMAIN SERVICES deal with business logic that cannot live in an ENTITY. For example, transferring fund between two accounts.
  • INFRASTRUCTURE SERVICES are those service that are more technical in nature, for example sending out an email or SMS text message.

Operation names in SERVICES should come from the UBIQUITOUS LANGUAGE. Parameters and results of these operations should be domain objects to make them explicit. SERVICES should be used carefully, don't take away all the behaviors from ENTITIES and VALUE OBJECTS and put them in SERVICES.

References:

1. Domain-Driven Design by Eric Evans
2. Power Use of Value Objects in DDD by Dan Bergh Johnsson
3. EvansClassification by Martin Fowler