DCI in Groovy

DZone 's Guide to

DCI in Groovy

· Java Zone ·
Free Resource

DCI (Data Context Interaction) is a new way to look at object oriented programming. If you’d like to read some theory to see the difference between DCI and traditional OOP there is a nice article coverting the topic:

And this presentation can be very helpful too:

In this post I’d like to show one simple example of a DCI program written in Groovy.

It isn’t easy to use DCI in Java as by its nature DCI requires sharing behavior between classes and Java doesn’t provide any decent ways to do it. But Groovy does - mixins.

Mixin is a very interesting approach allowing you to share a piece of behavior between several classes. The approach has been used by Smalltalk developers for more than 30 years but it started being popular in ‘more or less mainstream’ languages only a few years ago. To demonstrate how to use mixins in Groovy for implementing DCI I’ll use write a simple app:


  1. We have users
  2. We have companies
  3. Users can follow users
  4. Users can follow companies
  5. Users are entities stored in a database
  6. Companies are entities stored in a database

Basically, we have two domain classes: users and companies and usecases: when a user starts folllownig a company and he starts following another user.

Firstly, let’s create our domain classes:

class User {
    int id
    String name
    int age
    List followers

class Company {
    int id
    String name
    String country
    List followers

And a simple Database class representing persistent infrastructure of a real application:

class Database {
    private users = [
        1: new User(id: 1, name: 'Johh', age: 25, followers: []),
        2: new User(id: 2, name: 'Piter', age: 25, followers: [])
    private companies = [1: new Company(id: 1, name: 'BigCompany', country: 'Canada', followers: [])]

    User findUserById(int id){

    Company findCompanyById(int id){

    void updateUser(User user){
        users[user.id] = user

    void updateCompany(Company company){
        companies[company.id] = company

Domain objects in DCI aren’t smart. They don’t provide methods for all possible use cases. They don’t interact with each other in complex ways. Instead, they have a set of fields and a bunch of convenient methods to access them.

All our business logic is concentrated in roles. Role is a piece of behavior that we can mix to our domain classes to solve business problems. We’ll need two roles for our toy application:

class Follower {

class Following {
    void addFollower(follower){
        followers << follower

Follower is a marker role. It isn’t necessary to create such a kind of a role but I like to do it as it clarifies my intent.

A bit of Groovy meta programming to make the syntax of adding a new role to a domain object better:

Object.metaClass.addRole = {role->
    delegate.metaClass.mixin role

So, instead of:

object.metaClass.mixin RoleName

it will look like:

object.addRole RoleName

The only part that left is a context which will extract domain objects from the database, assign some roles to them and start a business use case:

class FollowersListContext {

Database db

void addFollowerToUser(int followingUserId, int followerUserId){
def following = db.findUserById(followingUserId)
def follower = db.findUserById(followerUserId)

following.addRole Following
follower.addRole Follower
following.addFollower follower

db.updateUser following

void addFollowerToCompany(int followingCompanyId, int followerUserId){
def following = db.findCompanyById(followingCompanyId)
def follower = db.findUserById(followerUserId)

following.addRole Following
follower.addRole Follower
following.addFollower follower

db.updateCompany following

Database db = new Database()
def context = new FollowersListContext(db: db)
context.addFollowerToUser(1, 2)

It may not be the most impressive example as we share only one line of code but it shows how all pieces work together. In a real word example roles will do much more than just adding an item to a collection. As a result this kind of decomposition will allow us to split complex behavior and avoid monster classes with thousands lines of code.

Having such a powerful language as Groovy it is not hard to adjust our code and make it look a bit better. For example, we can use such code for assigning roles:

def following = db.findCompanyById(followingCompanyId).inRole(Following)

Or even such code (though it looks a bit weird for me):

Following.playedBy(company).addFollower Follower.playedBy(user)


From http://victorsavkin.com/post/4243788839/dci-in-groovy


Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}