Friday, September 23, 2011

Using SOLID to Implement Fizz Buzz


So I was having lunch with @jeffreypalermo@dannydouglass, and my other teammates, and they were chatting about interview processes/techniques. Jeffrey was in town for our annual HeadSpring training and mentioned the infamous fizz buzz problem and I couldn’t but think about how I’d implement it...cleanly!! One given is that whomever reads it does not want to see a proliferation of if statements. But they have to get written at some point, right? So thinking about modern practices and design principles, I thought to myself…why not let SOLID guide me here? And that’s exactly what I did.
















So there are several components at play here; the FizzBuzzCommandProcessor and the FizzBuzzCommandRetriever. I took the processor technique from Jeffrey when he mentioned how they implemented the rules engine. I thought it was pretty cool and would be fun to implement something similar on my own. And with the advent of CQRS, I’m just really hooked on commands in general. They promote such strong usage of Single Responsibility Principle (SRP). The command processor takes input from the command retriever, and matches up each command with the value that it can handle. That’s it.
using System.Collections.Generic;

namespace ADubb.FizzBuzz
{
    public interface IFizzBuzzCommandProcessor
    {
        void Process(IEnumerable<int> numbers);
        void Process(int number);
    }
}
using System.Collections.Generic;
using System.Linq;

namespace ADubb.FizzBuzz
{
    public class FizzBuzzCommandProcessor : IFizzBuzzCommandProcessor
    {
        static readonly IEnumerable<IFizzBuzzHandler> HandlerCache;
        static readonly FizzBuzzCommandRetriever CommandRetriever;

        static FizzBuzzCommandProcessor()
        {
            CommandRetriever = new FizzBuzzCommandRetriever();
            HandlerCache = CommandRetriever.GetHandlers().ToList();
        }

        public void Process(IEnumerable<int> numbers)
        {
            numbers.ToList().ForEach(Process);
        }

        public void Process(int number)
        {
            var handlers = HandlerCache.Where(h => h.CanHandle(number));

            handlers.ToList().ForEach(h => h.Handle(number));
        }
    }
}

Next there is the FizzBuzzCommandRetriever. I decided to keep things simple and only scan the currently executing receiver for command handlers as opposed to the entire AppDomain. This guy helps me separate the responsibility of finding finding IFizzBuzzCommandHandlers at runtime. That’s all it knows how to do. We've achieved a clean separation between the what and the how.

using System.Collections.Generic;

namespace ADubb.FizzBuzz
{
    public interface IFizzBuzzCommandRetriever
    {
        IEnumerable<IFizzBuzzHandler> GetHandlers();
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;

namespace ADubb.FizzBuzz
{
    public class FizzBuzzCommandRetriever : IFizzBuzzCommandRetriever
    {
        public IEnumerable<IFizzBuzzHandler> GetHandlers()
        {
            var handlers =
                Assembly.GetExecutingAssembly().GetExportedTypes().Where(
                    t => typeof(IFizzBuzzHandler).IsAssignableFrom(t) && t.IsClass)
                    .Select(Activator.CreateInstance)
                    .Cast<IFizzBuzzHandler>();

            return handlers;
        }
    }
}
Then I have actual implementations of IFizzBuzzCommandHandlers. These are consumed by the processor and told to act on their respective inputs. Clear as day.
namespace ADubb.FizzBuzz
{
    public interface ICommandHandler<in TType>
    {
        bool CanHandle(TType target);
        void Handle(TType target);
    }
}
namespace ADubb.FizzBuzz
{
    public interface IFizzBuzzHandler : ICommandHandler<int>
    {
    }
}
using System;

namespace ADubb.FizzBuzz
{
    public class MultiplesOfThreeFizzBuzzHanlder : IFizzBuzzHandler
    {
        public bool CanHandle(int target)
        {
            return target % 3 == 0;
        }

        public void Handle(int target)
        {
            Console.WriteLine("{0} is a multiple of 3.", target);
        }
    }
}
using System;

namespace ADubb.FizzBuzz
{
    public class MultiplesOfTwoFizzBuzzHanlder : IFizzBuzzHandler
    {
        public bool CanHandle(int target)
        {
            return target % 2 == 0;
        }

        public void Handle(int target)
        {
            Console.WriteLine("{0} is even.", target);
        }
    }
}

Lastly we have the Open Closed Principle (OCP) that comes at play. I was telling Jeffrey how the template pattern lends itself very suitable to the OCP. Since we have the command retriever, it’s easy for us to plug additional handlers into the pipeline. It’s also just as easy to take them out. What I admire most is that the mere act of adding or removing a class from the assembly has no adverse affect on the runtime. See for yourself. Just comment out the class definition for one of the handlers and observe as its output never gets logged to the console. Our template comes into play with inheritance of course. There is an IFizzBuzzHandler that each handler implements. It’s merely just a marker interface. This same concept is applied with handlers in NServiceBus. I like J

Program...
using System.Linq;

namespace ADubb.FizzBuzz
{
    class Program
    {
        static void Main()
        {
            var oneToOneHundred = Enumerable.Range(1, 101);
            IFizzBuzzCommandProcessor fizzBuzzCommandProccessor = new FizzBuzzCommandProcessor();
            fizzBuzzCommandProccessor.Process(oneToOneHundred);
        }
    }
}
Output...



























Overall, it was nice to watch all the constructs come together and play nicely with one another. Each component has a single responsibility. Nice fine grained, granular classes that don’t know how to do too much. They specialize at a specific task. They know how to do one thing really, really well. And that’s it.