Recap on Lecture 4 - Domain Driven Design

Friday, July 4, 2008

Domain-driven design is focused at the Domain Layer which is one of the common layers in an object-oriented system with a multi layered architecture. Complex domain designs should be based on a model. The domain model should form a common language for describing system requirements, that works equally well for the business users or sponsors and for the software developers. In Domain-driven design, we only need to concern about object oriented concepts. We capture domain elements and represent them in object oriented concepts like objects, methods, etc. The design needs to be both nice and usable as it is the foundation for rest of other stages of software life cycle. When designing, we need to think whether we can implement this design in the real world. We should be able to change the technology, if we couldn’t achieve the design with the existing technology. We should not keep two separate designs for analysis & design phase and for implementation. Design model and the implementation model should be aligned. There should be feed back loop through out the life cycle.

It is needed to avoid mismatches between domain experts and software developers. Multiple words can be used to represent same things and one word can be used to represent the two things. We should avoid those kinds of language ambiguities.

Model Driven Design is broken down into the following artifacts:

  • Entities
  • Value Objects
  • Factories
  • Services
  • Aggregates
  • Repositories

Each one of these artifacts complements one another and allows us to gain greater insight into the business domain. Ubiquitous Language is the backbone or glue rather that holds all these artifacts together.

Services: Services are not part of the domain, but need to carry out the domain. Considering bank domain, transactions can be identified as domain services and providing pawning, and secure safe are some examples for infrastructure service. We can use services to capture responsibilities and system requirements which are not directly related to the domain. Class should have only one responsibility assigned to it.

Modules: In a complex system the model tends to grow bigger and bigger, so it is necessary to organize the model into modules. Therefore modules are used to avoid complexity. Divide and conquer is the method used to handle complexity. Dependencies between modules should be removed. Modules should be able to handle independently. Coupling should be less between modules. These modules also should reflect domain concepts like module naming.

Aggregate: An Aggregate is a group of associated objects which are considered as one unit with regard to data changes. Every aggregate has a boundary. It can be divided into normal aggregates and root aggregates. Root aggregate is the owner of other classes within the boundary. The root holds references to any of the aggregate objects, and the other objects can hold references to each other, but an outside object can hold references only to the root object.

Factories: Objects have a life cycle staring with creation, then retrieving, and ending with deletion. Factories can be used to create complex objects as hierarchies. When a Factory is not needed, we can use simple constructor to create objects. We have to identify correctly when factory is needed. Factories need to create new objects from scratch, or they are required to reconstitute objects which previously existed,

Senarathna P.D.E.(044036)

Comments About Lecture

Tuesday, July 1, 2008

Domain Driven Design

  • The idea of domain driven design is to capture all requirements in our model and can’t assign ad hoc responsibilities to domain classes. This comes with domain layer in layered architecture. Here we don’t concern infrastructure details and technology. We only need to concern about object oriented concepts. That means capture the concepts and represent those concepts in object oriented manner, like classes, objects etc… Normally these are commonly known things. However design should be nice and usable, because it becomes the foundation for rest of other process.

  • If the existing design cannot be afforded by using existing technology, it should flexible to change technology to achieve the design. It should not keep two designs for analysis & design and implementation. That should be same. So it can map one to one between design model and implementation model. When it is using only one design there should be a feed back loop through out the life cycle
  • Language can use different words to express same thing and can use one word to represent two things. These are wrong. Better way is to represent one word for one thing. Then we can reduce conflicts and provide more meaningful language.

  • Services are not part of the domain, but need to carry out the domain. Actually services capture responsibilities and system requirements. One of the best practice is one class should have only one responsibility. As an example consider the university domain and its parts like library, canteen, bookshop, examination department. All of these are services and library, canteen, bookshop are infrastructure services. So university domain can exist without this domain. But the service like examination department is domain services, means these are mandatory service for university domain. It can’t exist without that domain services.
  • We can use modules to reduce complexity. It’s very important to increase cohesion and reduce coupling. It’s important to remove dependencies between modules and provide the ability to work independently. There can be tight coupling within module and reduce the coupling among modules. As an example consider a DVD player and amplifier. Here there are many open jacks to connect other sub systems but no way to change interior of particular sub system. Also these modules should reflect domain concepts.
  • Every aggregate has a boundary. It can be divided into normal aggregates and root aggregates. Root aggregate is the owner of other classes. In the example we are discussed customer is the root aggregate. Contact info and address can’t change without knowing the customer. That means customer has full control of these two.
  • Object creation and assign something to object is two different things. As an example construct car and use car is two different things. Factories responsible for create objects. If we want to do a particular job we need to call objects. Repositories like directory. Those are help to find objects inside the memory. These repositories hide implementation details, means encapsulation is there. Here we don’t need to concern where the object is and only need to refer matching criteria.

S.R.S. Gunawardana - 044012

Recap of Domain Driven Design with comments by Sir

Domain Driven Design

Domain driven design comes in domain layer in the layered architecture. There we are not concerning about any particular technology or infrastructure, but object oriented concepts. We capture domain elements and represent them in object oriented concepts like objects, methods, etc. The design needs to be both nice and usable. The design which is nice but not usable is not worth and vice versa. When designing, we need to think whether we can implement this design in the real world. We should not keep two separate designs for analysis & design phase and for implementation. It should be the same design we should implement. Although there is a feedback loop through out the life cycle, the same design should continue through out the all stages of the software life cycle.


Language ambiguity:

We should avoid mismatch between domain experts and software developers.

We should also avoid;

  • Usage of multiple words to represent the same thing. For example debit & credit and withdraw & deposit to represent the same thing.
  • Usage of one word to represent two things.

We should avoid the language ambiguity.


Services:

If we take university domain there we can identify several services which are related to that domain. For example canteen, library, bookshop, examination dept, etc. Canteen, bookshop can be given as examples for infrastructure service and examination, other departments are examples for domain services. We can use services to capture responsibilities and system requirements which are not directly related to the domain. Without services we assign that responsibility to some other class which is not good. Because a class should have only one responsibility assigned to that. We use artificial classes to assign those responsibilities as services.

Modules:

To avoid complexity, we use modules. Divide and conquer is the method used to handle complexity. Since one person can’t comprehend the whole complexity, can use modules. We should remove dependencies between modules, so that they can be handled independently. Within sub system or modules, there exists high level of coupling. But between modules coupling is less. These modules also should reflect domain concepts like module naming, etc.

Aggregates and aggregate roots:

Also known as concurrency control and ownership. Every aggregate has a boundary. If we take a look at the figure above, can’t change contact info or address without knowing the customer. Customer is the owner of it. If two people are going to change this information, there would be concurrency issues. Customer is the one who have the control over the contact info and address.

Object life cycle:

Objects have a life cycle staring with creation, then retrieving, and ending with deletion. Use factories to create complex objects. Otherwise use a constructor. Consider previous figure; if all customers need to have contact information and how we are t enforce this rule? It’s not a customer class responsibility. So create a factory and assign that responsibility.


By: W.A.A.D. Wickramaarachchie [044044]