DDD DCI and Domain Events example

DDD is Domain-Driven Design , it is a methodology that include ubiquitous language, root entity , value object and aggregations..

DCI: Data, Context, Interactions is a programming paradigm invented by Trygve Reenskaug.

DCI keys:
1. keep our core model classes very thin.
2. logic/behaviour should be kept in roles.

Event Sourcing is a natural fit for software developers that want to capture the essence of business domains (especially the most complex ones) while staying decoupled from platform complexity or hard performance issues.

Next step, we show how combine these together by a example: Here is a Robot:










DDD tell us  a result as below:



Robot is a root Entity, it include CPU Sensor Motor Sonar entities, all is a aggregations.

By Object Design: Roles, Responsibilities, and Collaborations), it is a responsibility-Driven Design, and give a roles-and-responsibilities model, responsibilities is that knowing what; doing what;deciding what.

So in this example, Robot know what? do what?
Robot can feel or see or hear and detect. Feeling  and seeing and  hearing is the responsibilities as a intelligent robot role.

But where responsibilities will be in a object? all responsibilities will be designed as methods of Robot entity?
That will be a big model.


DCI says : No.

DCI think Responsibilities should be interactions of a Role   and will be injected into data model in context. so as below:

Robot entity is a DCI's data model , and seeing hearing or feeling is the interactions of a Role.

Other example such as BankAccount, it has three roles: two roles are design roles, BankAccount and FinancialAsset, another role is technical role: EJB's EntityBean for persitence.


How to implement above DCI design?

I have implement this Robot Example with open source Jdon framework 6.5,  in DCI context:

public String hello(String id) {
Robot robot = robotRepository.find(id);
IntelligentRole intelligentRobot = (IntelligentRole) roleAssigner.assign(robot, new IntelligentRobot());
return "Hello, " + intelligentRobot.hear();
}


public String touch(String id) {
Robot robot = robotRepository.find(id);
IntelligentRole intelligentRobot = (IntelligentRole) roleAssigner.assign(robot, new  IntelligentRobot());
return "Hello, " + intelligentRobot.feel();
}

Like BankAccount has a role :  EntityBean for persitence, Robot has too a role for persistence, but the role not operate directly dabatabse such as EJB's EntityBean, because database operatings  cost performance and slow, so we use concurrent pattern in here.

a PublisherRole is a event publisher of database operatings, by it Robot can save himself to send a event to repository, here :


@Introduce("message")
public class PublisherRoleImp implements PublisherRole {

@Send("saveme")
public DomainMessage remember(Robot robot) {
return new DomainMessage(robot);
}
}


here is the operatings database event subscriber:

@Component
@Introduce("modelCache")
public class RobotRepositoryInMEM implements RobotRepository {
.....

//enable Robot Model in-memory cache
@Around
public Robot find(String id) {
return memDB.get(id);
}

//saving event subscriber
@OnEvent("saveme")  
public void save(Robot robot) {
memDB.put(robot.getId(), robot);
}

.....
}

here is saving context:


public void save(Robot robot) {
PublisherRole publisher = (PublisherRole) roleAssigner.assign(robot, new PublisherRoleImp());
publisher.remember(robot);
}


example source download: robot.zip