Domain Driven Design

Service layer to domain layer?

Join in on the conversation over on the DDD mailing list.  You know you want to!

Domain Models and Pesistence

Paul Gielens has an interesting post on “Keeping the Domain Model free from Persistence Logic.”  Within the article he talks about using different patterns to help ensure persistence doesn’t creep into your domain model.  He also goes through the general architecture which he’s created to help ensure that a bidirectional relationship between his domain and persistence packages isn’t created. 

PS – you gotta love the name of his blog: 

another Endpoint to my thoughts

DDD: Reconstituting objects from multiple Repositories

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.

public class Customer {
    public int addressKey;
    public Address Address {
       get {
         if(address == null) {
            address = new AddressRepository().Load(addressKey);
        }
         return address; 
       }
}

Ok, so the above would work but is it really what we want? Using the above method we introduce a coupling between our Customer class and the AddressRepository. 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. So how can we remove the coupling to the AddressRepository AND remove the Repository outright?

public class Customer {
     public int addressKey;
     public Address address; 
     public Address Address {
          get { return address; }
     }
}

One option is to have to separate methods on our CustomerRepository for returning Customer objects with and without Addresses loaded.

public class CustomerRepository : DomainRepository {
   public Customer Load(int customerKey) {
        Customer customer = RetrieveFromDataStore(customerKey);
        return customer;
   } 
 
   public Customer LoadWithAddress(int customerKey) {
       Customer customer = Load(customerKey);
       DomainRepository addressRepository = this.RepositoryFactory.GetRepository(typeof(Address));
       customer.Address = addressRepository.Load(customer.AddressKey); 
       return customer;
    }
}

The negative to the above is that we have two different methods for loading customers. If we use .Load() and then try and access the address property we get a null which could cause users of the class to think that the Customer doesn't have an address which is not the case. On the positive side using the above design forces the users of the class to think about how the customer is going to be used. Rather then lazy loading the address we have it pre-populated which ensures we don't run into performance problems due to users not realizing that the property is lazy loaded and causing additional hits to the database. What other options do we have? Perhaps introducing a proxy object could help?

public class Customer {
    public Address Address {
         get { return addressProxy.Address; }
    }

    protected internal AddressProxy AddressProxy {
        set { addressProxy = value; }
    }

public class AddressProxy {
   private int addressKey;
   private DomainRepository addressRepository; 
   private Address Address;

   public AddressProxy(int addresskey, DomainRepository addressRepository) {
      this.addressKey = addressKey;
      this.addressRepository = addressRepository;
    }
    public Address Address {
     get {
          if(address == null) {
             address = addressRepository.Load(addressKey);
          }
          return address;
      }

And our CustomerRepository Load methods change to:

public class CustomerRepository {
    public Customer Load(int customerKey) {
         Customer customer = Load(customerKey);
         DomainRepository addressRepository = this.RepositoryFactory.GetRepository(typeof(Address));
         customer.AddressProxy = new AddressProxy(customer.AddressKey, addressRepository);
         return customer;
     }
}

The negative's of this solution is that we're introducing the proxy class into the Customer which is a little messier then I'd like. It'd be nice if our AddressProxy could inherit from our Address and provide a nice way of handling the loading of itself so that the Customer didn't have to use the AddressProxy. We could have the proxy overload all the properties of the address but that would be pretty ugly for all but the simplest of classes. I'm still not real pleased with the solution that I came up with here but it's at least a start. Perhaps all of my wonderful readers can help improve the "design"?

DDD: Aggregates & Repositories

There has been a lot of discussion recently about how to handle aggregates that contain other aggregates when building models using DDD. The discussion started a couple weeks ago when Udi posted his proposed solution. Udi suggested that we should add a .Save() method to our domain object that does nothing other then fire an event that will allow any interested "parties" to catch the event and do the appropriate processing. I don't like the idea of adding methods to our domain objects that only fire events. Having a .Save() method on an object implies that calling that method will save the domain object to the data store. Additionally if we're following DDD we try to avoid adding data access like behavior to any of our domain objects. We leave the data access "logic" to our repositories. Let's quickly review the scenario that Udi presented (which came from a comment on one of my earlier DDD posts). We have a Customer object which has an associated address.

public class Customer {
   // ... other props...
   public Address Address {
     get { return _address; } 
     set { _address = value; }
   }
}

When we save the customer we also want to save the associated address. Now if we're following DDD we know that Repositories will play a large role in the saving of our domain objects. Each of our Aggregates should have a Repository that is responsible for handling all data related tasks for all the objects in the aggregate. If address is part of the Customer aggregate we have nothing to worry about since the CustomerRepository would then be responsible for saving the address itself. For arguments sake let's continue with the assumption that the Address class is the root of it's own aggregate and has it's very own Repository. How should the CustomerRepository handle the address when the customer is saved?

Since we're following DDD we should embrace the fact that we're going to be using repositories to save our domain objects.

public class CustomerRepository : DomainRepository {
   public bool Save(Customer customer) {
         SaveCustomerToDataStore(customer);
         AddressRepository addressRepository = new AddressRepository(); 
         addressRepository.Save(customer.Address); 
         return true;
    }
}

As Steve Maine pointed out in one of his follow up posts, including the AddressRepository directly in the CustomerRepository creates a dependency between our repositories that we don't want. What if all the sudden the address needs to be saved by a different repository? How do we introduce a mock address repository into the equation during testing? Rather then hard coding the repository, we should implement a RepositoryFactory class. The RepositoryFactory will have the responsibility of knowing what repository should be used for each type of domain object. The knowledge will either be provided during initialization, via a configuration file, or perhaps will be covered by a framework such as PicoContainer. By introducing a factory into our design we decouple the AddressRepository from the CustomerRepository.

public class CustomerRepository : DomainRepository {
     public bool Save(Customer customer) {
          SaveCustomerToDataStore(customer);
          DomainRepository addressRepository = RepositoryFactory.GetRepository(typeof(Address));
          addressRepository.Save(customer.Address); 
          return true;
      }
}

Since we may not always want to use the default RepositoryFactory we should use dependeny injection to allow users of the CustomerRepository to change the factory that is used.

public class CustomerRepository : DomainRepository {
    public CustomerRepository(IRepositoryFactory factory) {
      this.repositoryFactory = factory;
    }

    public IRepositoryFactory RepositoryFactory {
        get { return factory; }
    }

    public bool Save(Customer customer) {
       SaveCustomerToDataStore(customer);
       DomainRepository addressRepository = this.RepositoryFactory.GetRepository(typeof(Address));
       addressRepository.Save(customer.Address); 
       return true;
     }
}

With our constructor in place we can very easily inject the proper repository factory into our CustomerRepository. This will allow us to swap out our repository during the testing of our components and will allow us to keep our repositories decoupled, both good things. Next on the plate is the loading of our customer and its associated address, which will come in another post....

Steve Maine Refactors his way to DDD glory

I was glad to see Steve's "Refactoring Our Way to Glory: An exercise in implementing a domain-driven design" post.  It not only addressed some concerns that I had with the event based solution that Udi presented but it also introduced a lot of other concepts that are extremely valuable.  I have some thoughts of my own on the topic that I'm hoping I'll get a chance to blog shortly.  For the time being get your fill from Steve Maine's solution.

How Domain Driven Design changed my way of thinking

Anyone who's been reading this blog for a while may know that I've always been a proponent of what I used to call a "rich Domain Model".  To get a feel for what I was referring to when I talked about a Domain Model check out the following posts:

Domain Driven Design has caused me to put some further thought into the topic.  I've always wanted everything wrapped up in my domain objects.  Rather then dealing with managers and domain objects and trying to decide what belongs where I always liked having everything packaged up in a nice rich domain model.  I was so attached to this approach that even after reading through DDD I was still in this camp.  It took a couple email's to the DDD mailing list for me to realize I had made the chapters in DDD say what I wanted, I made them read as if what I was doing was what was recommended.  This caused me to go back and re-read many of the chapters in DDD which helped me realize that the recommendations that were being made were much more in line with what I had called the Manager model in the past. 

Fortunetly for me I don't totally distort everything that was said in the chapters.  DDD does advocate a rich domain model, just not the type of rich domain model I had been using. 

Before reading DDD my domain objects had the following responsibilities:

  • Used DAL layer to retrieve items from the data store
  • Had deep relationships with other objects in the model.
  • Contained domain logic relevant the the real world object being represented by the domain object
  • Were used to retrieve single instances as well as collections of domain objects

After reading DDD my domain objects become a little simpler and give up much of their responsibility.  Rather then concerning themselves with multiple responsibilities the role of the domain object (Entity) is simply to model the real world object's data and behavior.  Some of the responsibility previously contained in my "rich domain model" has been moved out to Repositories.  Repositories take on the responsibility of returning objects from a data store.  They handle returning single instances of objects as well as collections of objects.  To ensure the repositories don't start taking on too much responsibility we introduce Factories.  Factories take data retrieved and turn them into actual domain objects.  Often times we have a coupling between our Repository and a Factory.  To ensure the two are loosely coupled I recommend the Factoring be configured using Dependency Injection.  This allows any Factory to be "inserted" into the repository and ensures that none of our objects are coupled to one another. 

As you may be able to see, my view on the wonderful world of domains has changed pretty significantly.  By moving much of the responsibility out of the domains and into other objects that can better handle the responsibility we're able to creating more flexible domain models.  Rather then gradually creating gigantic domain objects with all kinds of dependencies and way too much responsibility we create a set of components that make up our rich domain model. 

 

DDD: Repositories & Factories

Repositories are used to re-create instances of objects from a data source.  Rather then placing the burden of retrieving data for object creation within our domain objects we should separate out that concern into "Repositories".  A repository is responsible for retrieving the data for our objects from our data store and re-creating instances of these objects using the data.  By abstracting the data retrieval operations out of our domain objects we provide greater flexibility within our domain.  We also ensure that our domain objects don't end up with knowledge of things they just shouldn't.   Since our objects aren't junked up with all the logic for data retrieval and object creation they can stay focused on representing our domain and the domain logic that makes up our applications.

After a repository has retrieved the data for a domain object it needs to re-create the domain object using the data.  There are times when the logic for performing the loading of the object from the data is appropriate within the repository, however, we'll often want to create a Factory object for this purpose.  A factory is responsible for the creation of objects.  The factory may be responsible for creating new object instances, as well as re-creating instances of objects from data.  By separating responsibility of object creation out of the repository we allow the repository to stay focused on its tasks of retrieving domain data out of the data store. 

Let's look at a quick example:

public class Customer {
   private string _firstName;
   private string _lastName;

   public string FirstName {
    get { return _firstName; }
    set { _firstName = value; }   
   }

   public string LastName {
    get { return _lastName; }
    set { _lastName = value; }   
   }
}

public class CustomerRepository {
   public Customer FindByID(int customerID) {
      IDataReader dataReader = ...;
      return new CustomerFactory().Create(dataReader);
   }
   public bool Save(Customer customer) {
      // save customer
   }
}

public class CustomerFactory {
  public Customer Create(IDataReader dataReader) {
    Customer customer = new Customer();
    if(dataReader.Read()) {
      customer.FirstName = dataReader["FirstName"].ToString();
      customer.LastName = dataReader["LastName"].ToString();
    }
    return customer;
  }
}

// UI Code
CustomerRepository repository = new CustomerRepository();
Customer customer = repository.FindByID(99);

// update fields/properties
...

repository.Save(customer);

By separating the responsibilities of data retrieval into our Repositories, and object creation into our Factories we allow our domain objects to stay focused on representing the domain.  We also allow our applications to become more de-coupled which allows us to more easily test our applications. 

 

Hooking your Domain Model and UI Layer

I've recently come across a couple of articles that identify the problem of mapping domain objects to the UI layer.  Paul Wilson suggests that we might be able to solve the problem by implementing a UI Mapper.  A UI Mapper would serve a similar purpose as the OR Mapper.  However, rather then mapping our object to our relational database as we do with our OR Mappers, we use the UI Mapper to map our objects to our user interfaces.  To continue on with some thoughts from the blogosphere we travel over to Jimmy Nilsson blog, where he wonders if the recent buzz surrounding the topic is a sign of things to come.

I haven't put a ton of thought into the topic, however, I think we can gain efficiencies from a UI Mapper as we can with OR Mappers.  On a recent project I didn't exactly flesh out a complete UI Mapper, however, I did do some UI Mapper'ish things to help speed the development of the UI of the application.

On many project in the past I've gotten a little bored writing a bunch of repetitive code to load data within my domain objects into my UI, as well as pulling information out of the UI and placing it into my objects.  The process went something like this...

protected void Page_Load(object sender, EventArgs e) {
  if(!Page.IsPostBack) {
     Customer customer = new CustomerRepository().FindById(99); 
     LoadFormFormCustomer(customer);
  }
}

protected void saveButton_Click(object sender, EventArgs e) {
  if(Page.IsValid) {
    Customer customer = new Customer();
    LoadCustomerFromForm(customer);
  }
}

private Customer LoadCustomerFromForm(Customer customer) {
  customer.FirstName = firstName.Text;
  customer.LastName = lastName.Text;
  // and on and on and on....
}

private void LoadFormFormCustomer(Customer customer) {
  firstName.Text = customer.FirstName;
  lastName.Text = customer.LastName;
  // and on and on and on....
}

Rather then continuing on the same basic path outlined above I set out to automate the process and reduce the amount of code required for creating "edit pages" within my application.  The solution I developed uses reflection to automatically load forms from domain objects, and domains objects from forms.  I created a controller class that takes a domain object and control as parameters.  The controller then loops over the properties of the domain object (via reflection) and finds controls on the form with a matching ID. 

Control foundControl = control.FindControl(property.Name);

If a control is found for the property the controller loads the control with the value within the associated properties of the domain object.  With this infrastructure in place the edit page for the Customer becomes much simpler:

public class CustomerEdit : Steve.Eichert.Sample.Web.UI.EditPage {
  
protected override Type DomainType() {
   
return typeof(Customer);
  
}
}

Could UI Mappers be the next big thing?  Maybe, maybe not, all I know is my simple UI Mapper saved me from writing a bunch of boring repetative code and allowed me to concentrate on developing the domain logic within the application which in my opinion is a very good thing.

DDD: Ubiqitous Language

One of the primary focuses of DDD is ensuring that a Ubiquitous Language is used.  What this essentially means is that everyone, and yes I really mean everyone, involved in the project uses the same terms to describe the system.  Typically as software developers we create our own language in which we speak to describe the various aspects of our software design.  When we then talk to business users we use a different language.  We usually justify these two languages by saying that the business users simply "wouldn't understand" what we were talking about if we tried speaking "our" language to them. 

By speaking in two different languages we create a gap between the developers on the project and the business users who are defining how the application should work.  We miss the opportunity to give proper names and meaning to the objects within our domain.  Although we often think we understand the business of the clients we work for, we often times don't know nearly as much as we think.  The analysts have expertise in the domain, we're just trying to gain some of the knowledge that they've accumulated over the course of their career.  Rather then finding our own names for "components" within the system we should take the business users lead. 

Before I get to far, let me ensure you that I don't think we can simply take everything the business users says and apply it directly to our domain.  We will certainly have to train them to understand parts of our terminology as well.  There has to be collaboration, we need each other to develop the best domain model possible for the systems we develop.

It's not enough to simply use the same language among our internal development teams as well as with the business users.  We need to listen carefully to how we describe the system with the ubiquitous language and look for areas that aren't clear.  We need to refine the language constantly to ensure it keeps up with all the new information we gather from our business users.  When we describe the system the ubiquitous language MUST be used.  By forcing ourselves to use the ubiquitous language at all times we provide ourselves with that much more opportunity for improving the domain.  As we hear ourselves talk about the domain with the ubiquitous language we will identify areas that are confusing, unclear, and desperately need "refactoring."  As the ubiquitous language is updated so to should the domain be updated.

After reading DDD I've begun to notice how much of a divide we create in order to speak the language of different groups of people.  We describe systems one way for fellow developers, another way for user experience and design folks, a third way for project managers, and yet another way for the business users (our client).  I'm still far from knowing how to really apply this in all circumstances, however, I believe having a ubiquitous language and forcing ourselves to use it at all times can certainly help improve our domain.  I am still skeptical that it can really be used with every individual on every project.  What do you think?

 

Domain Driven Design

Over the past month or two I've been trying to wrap my head around the ideas and principles of Domain Driven Design, and how it affects how I develop software.  A lot of the concepts and principles are things that I've been following for a long time, I just didn't call them by the "proper" names.  In an effort to flesh out some of my thoughts on DDD I'm going to be posting a few entries about some of the core principles that have stuck in my head after reading DDD.  As a disclaimer all the information that I write regarding DDD is my interpretation of what I read and not necessarily what Eric and friends have laid out.

To start if you haven't already read Domain Driven Design please go buy it now, so that I can get a bunch of feedback and reaction from you all as I write about my interpretation and thoughts surrounding it.  Ok, all done?  Really, go now

Ok, now that we have that out of the way lets lay out a temporary list of things to write about:

Stay tuned for the first installment.....aren't you sooooo excited!?!?!

[Side Note: I finally bucked up for BlogJet, you gotta love the simplicity of its design/ui]

Domain Driven Design rocks!

I'm only about half way through Domain Driven Design by Eric Evans but I'm thoroughly enjoying what I've covered so far.  I think Matin's PoEEA and Evans DDD should be required reading for all!  Look for a more detailed review in a couple weeks when I finish it off...