Product or Project Focused

A software development team in an organization should be able to focus on the core domain that reflects the business it’s serving. Developers on the team should be able to iterate and further refine the domain model based on the evolving input and feedback of the domain experts. The business people, domain experts and developers treat the software as a product, further evolving throughout a long period of time so far as it provides real value.

Sounds like an ideal world. As we all experienced during our careers, reality is almost never that shiny. Lots of businesses don’t see their software as a product. Instead they pride themselves as “project” organizations, always ready to sacrifice long-term thinking and quality for impossible deadlines. The result is usually a code-base with a lot of technical debt spread with project specific features. This is what we developers call the Big Ball of Mud.

What I just described here are two complete opposites. There are lots of businesses that have a product mindset, and there are lots that have a project mindset. But most organizations sit somewhere in between. In these organizations there is some kind of balance.

A while ago, fellow Elegant Coder David Starr wrote one of the best articles I’ve read in quite some time which is related to this topic. I urge you to read this excellent writing at least a couple of times.

“As per the agile manifesto, the only real measure of success is working software. Success on a development team should never be measured in volume of tickets serviced. That sort of measure is appropriate for an operational support team.”

In a project organization, development teams are commonly treated as an operational support team, usually not given the right amount of time to focus on the core domain of the business.

“If your team is spending less than 75% of its time doing this, you may be on the verge of “going operational” which ultimately means even less time available for new capability development. “Going operational” often represents defeat for a development team.”

As with all things in life, there should be a nice balance between product and project thinking with a majority of the focus on long-term development of the core domain model. But then again, there are things that science knows, and then there are things that companies do.

Premature Abstraction

The first time I read the GoF book, I didn’t understand it. This was because I didn’t had a decent understanding of the principles of object-oriented programming at the time. A while after, I read the book Design Patterns Explained. In this excellent book the author formulated the core thought behind the design patterns in the GoF book. He states that when a particular concept varies, it should be encapsulated (by means of an abstract class or and interface). This was a real eye opener for me and guided me to understanding the design patterns described in the GoF book.

But what I also learned after several years is that introducing abstractions in code is not a free ride either. There is a time and place where you want abstractions. I used to add abstractions in domain models all over the place, as soon as I possible could. Now I try to avoid them until the last responsible moment. Only when I gain a deeper understanding, when I start to see variations of the same concept popping up, when concrete implementations start to cause pain, only then am I prepared to consider adding a new abstraction.

Suppose that we have the concept of a communication channel in a particular domain model. If we have more than one communication channel, say SMS, telephone and email, then an abstraction is warranted. Then we might want to introduce an ICommunicationChannel interface. But if we only have SMS as communication channel, then no abstraction is needed. If new communication channels are being added over time, only then do we refactor the code.

Sometimes my brain tricks me into the premature abstraction path. It also happens that I’ve postponed introducing an abstraction a bit too long. I do make mistakes. Who knew? But I do gained some awareness over the years.

Node-m-r – A Simple CQRS Example using Node.js

Anyone learning about DDD, CQRS and/or event sourcing has probably read the source code of Greg Young’s simple CQRS example at some point or another. This is one of the simplest examples possible demonstrating the practical side of CQRS and event sourcing, originally developed using .NET.

I made an attempt to rewrite the source code of this example using Node.js, trying to apply as many features of the core library as possible, particularly streams and event emitters. For example, the implementation of the base aggregate root object uses an event emitter internally for applying events in derived objects. An aggregate root is also a writable stream, which is used by the repository for replaying events. The report aggregators are also writable streams, which receive events from the message bus.

I’ve put the resulting source code up on GitHub. This is still very much a work in progress though. Some improvements that I’m considering is spawning a separate child process for both the command handlers as well as the report aggregators. No data is being persisted at the moment, so everything is stored in memory. Adding physical data stores is something that I’m also looking into. There’s no UI available either. You can run the example by executing the following command:

$ node src/application.js

Have a look at the source code and let me know what you think.

Until next time.

Generic Value Object

I just wanted to share my attempt for implementing a generic base class for Value Objects, popularized by Eric Evans and the Domain-Driven Design community. I must say that I got heavily inspired by Jimmy Bogard’s implementation, which got me thinking about such an approach. Contrary to his implementation, I used static reflection instead of dynamic reflection in order to determine which fields to use for equality and string representation.

public abstract class ValueObject<T> : IEquatable<T>
    where T : ValueObject<T>
{
    private List<PropertyInfo> Properties { get; set; }

    protected ValueObject()
    {
        Properties = new List<PropertyInfo>();
    }

    public override Boolean Equals(Object obj)
    {
        if(ReferenceEquals(null, obj)) return false;
        if(obj.GetType() != GetType()) return false;

        return Equals(obj as T);
    }

    public Boolean Equals(T other)
    {
        if(ReferenceEquals(null, other)) return false;
        if(ReferenceEquals(this, other)) return true;

        foreach(var property in Properties)
        {
            var oneValue = property.GetValue(this, null);
            var otherValue = property.GetValue(other, null);

            if(null == oneValue || null == otherValue)  return false;
            if(false == oneValue.Equals(otherValue)) return false;
        }

        return true;
    }

    public override Int32 GetHashCode()
    {
        var hashCode = 36;
        foreach(var property in Properties)
        {
            var propertyValue = property.GetValue(this, null);
            if(null == propertyValue)
                continue;

            hashCode = hashCode ^ propertyValue.GetHashCode();
        }

        return hashCode;
    }

    public override String ToString()
    {
        var stringBuilder = new StringBuilder();
        foreach(var property in Properties)
        {
            var propertyValue = property.GetValue(this, null);
            if(null == propertyValue)
                continue;

            stringBuilder.Append(propertyValue.ToString());
        }

        return stringBuilder.ToString();
    }

    protected void RegisterProperty(
        Expression<Func<T, Object>> expression)
    {
        Check.Argument(expression, "expression").IsNotNull();

        MemberExpression memberExpression;
        if(ExpressionType.Convert == expression.Body.NodeType)
        {
            var body = (UnaryExpression)expression.Body;
            memberExpression = body.Operand as MemberExpression;
        }
        else
        {
            memberExpression = expression.Body as MemberExpression;
        }

        if(null == memberExpression)
        {
            var message = ResourceLoader<ValueObject<T>>
                              .GetString("InvalidMemberExpression");
            throw new InvalidOperationException(message);
        }

        Properties.Add(memberExpression.Member as PropertyInfo);
    }
}

This generic base class takes care of the equality by overriding Equals and GetHashCode from the Object class and implementing the IEquality interface. It also takes care of a default implementation of the ToString method.

Using this base class significantly reduces the amount of code for implementing  a value object in the domain.

public class Tag : ValueObject<Tag>
{
    public String Name { get; private set; }

    public Tag(String name)
    {
        Name = name;
        RegisterProperty(value => value.Name);
    }
}

And that is that. The only thing I’ve omitted in this example is the validation of the specified name.

I’ve been using this base class in a couple of projects now, and so far, I’ve been very pleased with the results although it can always be improved. I’d love to read your comments.

Indi Young on Mental Models

I was fortunate to sit in a lecture today by Indi Young, co-founder of Adaptive Path and author of the recently published Mental Models, Aligning Design Strategy with Human Behavior. Ms. Young described her framework for constructing Mental Models, which are models representing a user’s thought process as they interact with a system. A Mental Model endeavors to give designers and application developers a usable way to see the system under development through the eyes of a user.

It is an interesting idea and an obvious compliment Domain Driven Design and Behavior Driven Design. The intent of the Mental Model is to allow designers to envision a user’s thought process and although it isn’t out-of-the-box simple, it is inherently useful.

She had some great feedback for our teams on creating more effective personas and user scenarios. Specifically, keep the personas behavior focused. For instance, I don’t need to know that Harold is a 38 year old fat guy, but I do need to know that he struggles to find content he is after on the web. Make sense?

At any rate, I have every good intention of reading her book and look forward to augmenting my toolbox with Mental Modeling.