Introducing DCI to the Perl world.

For those who are not aware, there is a newish methodology called DCI (Data, Context, Interactions) which attempts to solve the problems of OOP. DCI was designed and proposed by the same guy that created the MVC concept that has become hugely successful. DCI is an attempt to group methods with their use cases so that interactions used by business logic and algorithms are more predictable.

The key to DCI is a separation of concepts:

  • Data: what the system is
  • Context: A use case
  • Interactions How objects interact within a context

I have created the DCI dist which includes helpers for writing Contexts and Interactions (DCI uses the terminology roles, but to avoid conflict with other perl concepts of roles I have called them casts.)

The DCI perl package can be found here:

If iframes are supported, this should show the synopsis for a common example of DCI.

Here are some links to information about DCI.

It can be hard to wrap ones head around DCI in the beggining. The important ideas are as follows:

Implement very simple data/model classes. You should avoid putting any methods into an object that implement business logic. Your data objects should not contain anything that requires utside context to understand.

When you have business logic, or an algorithm, you shoudl encapsulate it in a 'Context'. A context can be thought of much like a movie script. A context has many roles that need to be played. A single object may play any number of roles, however a role can never be played by more than one object. The context is responsible for assigning (or casting) the 'dumb' data objects, aka actors to the specified roles.

Within a context the idea of a role represents a set of methods an actor must provide. These methods only make sense within the greator context/encapsulation of the business logic or algorithm. You do not want these methods avalable to clutter or confuse the 'dumb' data object outside of the context.

The DCI::Context package provides sugar that makes defining a context very easy. You tell your context what roles need to be filled, and what Cast package should be used for that role. During construction you provide (role => dumb_object) for each role, the casts happen automatically. Once the roles are defined all you need is a method that kicks off the interactions for the algorithm/business logic.

The DCI::Cast concept of roles (or casts as my DCI package calls them) differ from the Moose concept or roles in one critical way. While both define methods that get injected into a root class, DCI's Cast methods are only present within the proper context; Outside of the context the DCI cast's methods are unavailable. Further this means that you do not need to import the cast/role when defining the class (wheras in Moose you must use the role in the package.)

This difference is particularily useful when you need to implement an algorithm that uses objects who's code is not under your control. With Traditional OOP you would subclass the objects you do not control, which can lead to messy hierarchies. In addition you may not control the code that produces the object instances in which case patching, or even worse moneky patching may be the only way to inject your methods.

With the DCI package you create casts, these casts wrap around a core object. The cast instance provides full access to the underlying object and it's API. In addition the cast object may define or override methods which you want to add to the underlying class. Finally the casts are also created with a reference to the context object which allows you to write context-specific interactions.


Well, I guess I'm one of those Neanderthals that don't get it. OOP is not better than procedural programming. People don't think in terms of "object manipulates other_object". They think, "I manipulate object and other_object". Like OOP and MVC before it, DCI is wishful thinking. People just don't think that way.

I think I'll start my own methodology called UTO: Users, Tools, and Objects. Give the user the tools to manipulate the (data) objects and let people come up with their ideas on how they're used.

@shawnhcorey - Give me a piece of knapped flint rather than a concrete realisation of a polymorphic class that supports a sub-class of an interface with operations Cut-skin-from-mammoth, & Dig-out-belly-button-fluff. Every time.

Even if people did think in terms of interactions between arbitrary sub-networks of discrete units from arbitrary classification systems with public and private behaviour, the world would still defy us. The idea that OO more naturally represents the real world is comforting, but, given the evidence of the last 25 years or so since the idea gained currency, wrong.

We don't even have a bullet-proof mathematical definition of what an algorithm is, for Turing's sake. Any expectation we will arrive at a definitive formalisation for an experience so necessarily subjective, and so utterly at the mercy of external agents (compiler, hardware, network, user, experience, mood, 3rd party etc), and that has to satisfy so many conflicting constraints (Do it now! Make sure it runs so fast it finishes before it starts! We want it to be maintained by toddlers whose first language is Medieaval Martian!), as transferring human thought into working software has to be at least a little naive.

Not that these things aren't worth exploring, any change of perspective can lead to useful insights. And of course perl is a fantastic base for that style of exploration, so good luck with that Chad.

Leave a comment

About Chad 'Exodist' Granum

user-pic I blog about Perl.