No Dots

On my last project, James and I started the slogan “No Dots”. “No Dots” reminds us that templates/views are “documents with holes” and should contain a very minimum amount of logic.

I amended the slogan to be: “Zero or One Dot”. You will see why shortly. The amended version was an artifact of using NVelocity. 

The example below is the reason behind the slogan.

Note: This example is in NVelocity, but it really applies to any template engine. 

#if(person.Age > 10)<div class="discount">Team</div>#end#if(person.Age > 20)<div class="discount">Network</div>#end#if(person.Age > 30)<div class="discount">World</div>#end

Is this code bad? Not really. The logic in the view is minimal.I say this view might be acceptable in a small project. The problem occurs when a project gets large. Why? Testing any logic in the view is hard and therefore does not get tested throughly. This under-tested logic is a breading ground for new bugs.James and I created a solution to this problem that James coined as the Advocate pattern.

Does this “pattern” have another name? 

What is an Advocate?The advocate is a “plain old object”, living outside the view, that answers questions about a model or models for a specific view.Enough with the definition, we want to see the code.PersonAdvocate

public class PersonAdvocate{    private Person person;    public PersonAdvocate(Person person)    {        this.person = person;    }    public void IList<Discount> Discounts    {        get        {            IList<Discount> discounts = new List<Discount>();            if(person.Age > 10) discounts.Add(new Discount("Team"));            if(person.Age > 20) discounts.Add(new Discount("Network));            if(person.Age > 30) discounts.Add(new Discount("World"));        }    }}

NVelocity Template

#foreach($Discount in $PersonAdvocate.Discounts)<div class="discount">$Discount.Name</div>#end

The above template code is an example of “One Dot”. Allowing “One Dot” means that only one object needs to be put into the template’s context. Sticking to “No Dots’ would force one object in the context per hole in the template. I am willing to allow “One Dot”, but no more.

The new version of the template is less complicated and more resistant to change. The decisions about what discounts to display are encapsulated in PersonAdvocate. Moving the logic from the template to the advocate made it easier to test and refactor. Advocates allowed us to fix buggy view logic that finally stayed fixed.


3 Responses

  1. Why do you not put the logic in the model?

  2. We did put the logic into the model when we could. The advocate should contain view only logic. Examples of this contain: building urls, building html elements and switching css classes based upon data in the model.

    I know the example did not represent that very well.

  3. […] in the view or the controller is difficult and error prone. We enforced a contract by implementing Advocates, but it would be nice if it were supported by […]

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )


Connecting to %s

%d bloggers like this: