Simplicity in Design

Previously I talked about Motivations for Dependency Injection and how we should keep our objects simple. Let’s talk about how we keep our objects simple…

I immediately think of one design principle that can be used to keep your objects simple:

Single Responsibility Principle (SRP) 

A class should have one, and only one, reason to change.

Shocking…isn’t it? Following that will lead you to use interfaces and keep your classes small and focused. There are a bazillion resources on SRP – have a look around the interweb and you’ll find plenty of references.

A lot of developers I’ve worked with seem scared to create a lot of classes. They have no problem making one big-ass class with over 100 methods but shy away from creating classes! When you start following the SRP you will have more classes but they will be small. In this particular case, smaller is good. I can read and understand what a class is responsible for if it is small. It’s OK to have a lot of classes as long as each one has a purpose.

Let’s do a before and after with the Global.asax that is generated when you create a new ASP.Net MVC application.

Before SRP:

public class MvcApplication : System.Web.HttpApplication
{
    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{\*pathInfo}");

        routes.MapRoute(
            "Default",                                              // Route name
            "{controller}/{action}/{id}",                           // URL with parameters
            new { controller = "Home", action = "Index", id = "" }  // Parameter defaults
        );

    }

    protected void Application\_Start()
    {
        RegisterRoutes(RouteTable.Routes);
    }
}

After SRP:

public class MvcApplication : System.Web.HttpApplication
{
    protected void Application\_Start()
    {
        RouteRegistrar.Register(RouteTable.Routes);
    }
}

public class RouteRegistrar
{
    public static void Register(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{\*pathInfo}");

        routes.MapRoute(
            "Default",                                              // Route name
            "{controller}/{action}/{id}",                           // URL with parameters
            new { controller = "Home", action = "Index", id = "" }  // Parameter defaults
        );

    }
}

It seems like a trivial difference but it is important – I have moved the responsibility for registering routes into a class whose sole responsibility is to register routes. The MvcApplication class still has to call the Register method, but that is its responsibility – to bootstrap other modules. But wait, there’s more! Now if I have to change the routes I only have to modify the RouteRegistrar class. I don’t have to touch any code in the MvcApplication class because of the change in the RouteRegistrar. This gives me confidence, backed up by unit tests, that I am less likely to break something in the MvcApplication class. Powerful stuff…

Enjoy!

This article is part of the GWB Archives. Original Author: Jon Dalberg

New on Geeks with Blogs

  • We Won The One Award I Actually Care About

    Full Scale made the Inc. 5000 for the fifth year straight, the 12th listing across my three companies. Here is why the one award you cannot buy is worth stopping for.

  • Your Customers Build the Features Now

    I let a tool I liked sit dead for a year rather than build the features I wanted. An MCP server meant I never had to, and your customers can do the same to your product.

  • Get the Size of a Directory in Linux the Easy Way

    du -sh for the quick answer, ncdu for the cleanup, df for the disk itself: every command for checking directory size in Linux, plus why du and df never agree.

  • Vim Search and Replace: The Ultimate Guide

    One :%s command replaces every match in a file before a find dialog would even open. The Vim substitute patterns worth the muscle memory: flags, ranges, capture groups, and multi-file edits.