DCI is an architectural pattern that aims to cleanly separate code for system behavior from code representing the domain model. It focuses on modeling interactions rather than classes. In DCI:
- Data represents the domain model and is stable over time.
- Context enacts a specific use case by mixing roles into participating objects.
- Interaction defines methods that carry out the use case by being mixed into role modules.
- A controller starts a use case by instantiating a context, which finds objects and mixes in roles to execute the interaction methods.
DCI aims to give interactions first-class status in the code and provide an object-oriented view of use cases that is closer to how people think about
3. History of DCI
Trygve Reenskaugs ideas about role based modeling in early
2000 (same guy who invented MVC in the late seventies)
Working design model in 2006
Working prototype in mid 2008
Complement to MVC
4. Why DCI?
MVC fails to capture behaviour
There's no apparent place to put interactions
(exception: simple actions that involves a single object)
Model should represent things
Things should be stable
Natural difference between what an object is and
what it does. Why not in the code?
5. Goals with DCI
Giving system behaviour first class status
Cleanly separate code for rapidly changing
behavior from code for slowly changing domain
knowledge
Object style of thinking that is close to peoples
mental models rather than class style
6. Data
What the system is
Closely corresponds to the Model
Reflects the domain structure rather than behaviour
7. Context
Context is a class (instance) which enacts one (or
more) use cases
Instantiated by a user (controller) action
Mixes in participating objects with Roles
The context is responsible for acting out the use case
8. Interaction
What the system does
Methods in role modules
Implemented by mixing in objects with Roles in a
given Context or use case
9. Executing DCI
Controller action starts a use case by instansiating a context
class
The context finds (or creates) the objects that are
participating in the use case
The context mixes in all the roles needed into the objects
The context invokes the role methods on the objects and
starts the use case enactment
10. Money transfer example
Bank - send money to another account
SendMoneyContext
account account
SourceAccount DestinationAccount
send(amount) verify(amount)
deposit(amount)
11. My implementation
Training app
Attend a training event
UserAttendsEventContext
user event
AttendingRole PublicEventRole
attends(event) attend_on_google(user)
12. What is it good for?
Kind of awkward to deal with context instances - bad
implementation?
Class methods belonging to roles or object?
Simple console usage must also follow the context
Easy to find specific methods (if used consistently)
Fat models go on crash diet!
Easy to maintain
Easy to follow an entire use case