Dogma, Pragmatism and the Rule of 3

originally posted on the Pluralsight tech blog

So There I Was

A few colleagues and I were happily coding away in our daily mob, writing a service that was responsible for listening to messages and persisting them to a database. We eventually arrived to this:

public void HandleMessage(AddressUpdated message)
{
    var address = new Address
    {
        Street = message.Street,
        City = message.City,
        State = message.State,
        Zip = message.Zip
    };

    addressCache.Save(address);
}

Being the pattern junky that I sometimes am, it occurred to me that we need a mapper for mapping the

AddressUpdated

message to the

Address

model that we are persisting to the database. A few keystrokes later:

public void HandleMessage(AddressUpdated message)
{
    addressCache.Save(Address.MapFrom(message));
}

I proudly sat back, confident that I had made the world a better place. My ever astute colleagues helped guide me back to reality with the following questions:

Do we really need that mapper?
We are only doing this mapping in one place, is this refactor premature?
Do we get anything for this additional complexity?

My mind began to enumerate over the reasons why we did in fact need it. We could test it in isolation, it made the code more terse and we could benefit from reuse! Thing is, we didn’t need any reuse yet. Also, we were already testing this component easily. It did make our code more terse, but only by moving the mapping code elsewhere. Realizing the mob was right, which is typical, we deleted the mapper and kept moving forward.

A Solution in Search of a Problem

Commuting home that night, I turned the mapper experience over in my mind. After some thought, I concluded that I had a solution in search of a problem. On a previous project I had used this mapper pattern with success and I was excited to use it again.

In the mob, I saw an opportunity to use this mapper pattern. Stressing the word opportunity here, what I did not have was a need for the mapper. The dogma inside me demanded that every mapping needs a mapper. Fortunately, the pragmatism of my colleagues stepped in and steered us back on course and away from spending cycles on something that we didn’t need.

The Rule of 3

Perfectionism and pragmatism are often at odds. How do you strike a balance between doing the perfect thing and doing the right thing?

At Pluralsight, we will often talk about the Rule of 3. This rule states that until you repeat yourself in at least 3 places, you probably don’t have to do anything about it. The thought behind this is that “doing something about it” typically means introducing complexity. The mapping example, although arguably trivial, highlights this rule. Following the Rule of 3, I shouldn’t write a mapper until I’ve mapped from AddressUpdatedMessage to Address at least 3 times.

I tend to get excited about new patterns. As exciting as they may be, maintaining and extending a code base full of applied-too-early patterns can quickly become difficult. The Rule of 3 helps me keep this in mind. What do you think?