Hack hack hack...

An open journal-- some of it written for you, but most of it is for me.

DCI

tl;dr

In DCI, Objects are viewed as whole objects rather than a composition of parts. e.g. fido is not seen as part class Animal and class MansBestFriend.

What is DCI?

  • Data
  • Context
  • Interaction

What are its goals?

  • To improve the readability of object-oriented code by giving system behavior first-class status;
  • To cleanly separate code for rapidly changing system behavior (what the system does) from code for slowly changing domain knowledge (what the system is), instead of combining both in one class interface;
  • To help software developers reason about system-level state and behavior instead of only object state and behavior;
  • To support an object style of thinking that is close to peoples’ mental models, rather than the class style of thinking that overshadowed object thinking early in the history of object-oriented programming languages.

The paradigm separates the domain model (data) from use cases (context) and roles that objects play (interaction). DCI is complementary to model–view–controller (MVC).

Why?

Some objects do different things in different parts of your application. You cannot use inheritance to cover the varying behaviour as the behaviours should change back and forth. The object just behaves different depending on the context.

DCI is about much more than just extending objects at runtime. It’s about capturing the end user’s mental model and reconstructing that into maintainable code.

What DCI is thought as, but isn’t

#extend as the go-to means of adding methods to objects at runtime.

The important thing to know about DCI is that it’s about more than just code. It’s about process and people. It starts with principles behind Agile and Lean and extends those into code. The real benefit of following DCI is that it plays nicely with Agile and Lean. It’s about code maintainability, responding to change, and decoupling what the system does (its functionality) from what the system is (its data model).

Data

  • The system are the actors
    • Object thinking instead of class thinking
  • correspond closely to the model objects of MVC.

An example of a data object could be a bank account. Its interface would have basic operations for increasing and decreasing the balance and for inquiring about the current balance. The interface would likely not offer operations that involve transactions, or which in any way involve other objects or any user interaction. So, for example, while a bank account may offer a primitive for increasing the balance, it would have no method called deposit. Such operations belong instead in the interaction part of DCI.

Context

the environment for which Data objects execute their Role. The goal of the Context is to connect Roles (what the system does) to Data objects (what the system is).

  • How the system looks and starts -> the director
  • There is always at least one Context for every one user story
  • Identify objects and assign them roles at runtime
  • Use case functionality = data object with assigned roles combined.

Interaction

  • “What a system does” -> its role
  • Roles played by objects
  • stateless
  • Call methods on self (=playing object)
  • Interactions are generic

DCI in rails

  • data => ActiveRecord model: The Data should really only consist of persistence-level methods, never how the persisted data is used.
    • DCI suggests that we keep our core model classes very thin. Zero logic, only data, if anything.
      • The logic/ behavior should be kept in roles. In Ruby we can nicely use mixins for that
  • context => Controller action or separate workflow case: we trigger our Context within the Controller.
  • roles => Module to mix in

DCI reduces the number of objects in your project, but increases the number of roles they play.

Characteristics of DCI

In DCI, Objects are viewed as whole objects rather than a compositon of parts. e.g. fido is not seen as part class Animal and class Friend.

  • An object-oriented program is a complex and dynamic network of objects, in the same sense that relationships between real-world objects are complex and dynamic.
  • The object has its own identity independent of the use case; this is the Data facet of DCI.
  • Roles are aliased names for their objects but are never separate objects themselves; that would cause self schizophrenia.

In the Wild

  • DCI depends on a design process that separates use cases from the data model.
  • DCI can be thought of as an event-driven paradigm, where some event (as a human gesture in an MVC architecture) triggers a use case. The use case can be short-lived or long-lived. The events are called triggers, and they are handled in the environment in which DCI has been embedded. This environment may be the Controller of a conventional MVC architecture or any other system-level code.
An over-simplified example
1
2
3
4
5
6
7
8
9
10
class Dog; end # Data
module Labrador # Role
  def bark
    ...
  end
end

fido = Dog.new # Context
fido.extend Labrador
fido.bark

Problems with DCI

  1. It requires a large paradigm shift. It’s designed to compliment MVC (Model-View-Controller) so it fits well into Rails, but it requires you to move all your code outside the controller and model. As we all know, the Rails community has a fetish for putting code in models and controllers. The paradigm shift is large, something that would require a large refactor for some apps. However, DCI could probably be refactored in on a case-by-case basis allowing apps to gradually shift from “fat models, skinny controllers” to DCI.
  2. It potentially carries performance degradations, due to the fact that objects are extended ad hoc.

History

DCI arose largely as an outgrowth of Trygve Reenskaug’s work on role-based modeling. Trygve had long recognized that Roles played a central part in the way we think about objects, and that the class-based progression of programming language technology took away much of the motivation to think about the objects in a program. That in turn made it difficult to reason about the program at run time. Further, the fact that object-oriented programming languages offered only classes to express program logic left the programmer at the mercy of the structural layout of the data to delineate behavior, which is unnatural compared with a delineating behavior on Role boundaries.

Sources

Comments