Sunday, June 19, 2016

Functional Creational Patterns


Much is made in the object-oriented world of applying Design Patterns. The majority of the time, the pattern in question is one from the canonical ‘Gang of Four’ book of the same name. I feel that I use these patterns in the manner intended — reusing a solution that has worked in the past to solve a new problem.

When learning a new paradigm, in my case functional programming with F#, I naturally had no previous solutions to fall back on, and thus no set of design patterns stored in my brain, patiently waiting their turn. This got me thinking about how well-known C# patterns can be applied to F# code, so I did a bit of searching and came up with a related talk by Scott Wlaschin. Whilst helpful, it was more about taking yourself out of an OO mindset as opposed to trying to reimagine existing patterns. I was still curious to answer this, which brought me to the question I’m about to answer in this post:

What do C# design patterns look like in F#?

I will do this in three installments to mirror those in the book: first Creational Patterns, then Structural Patterns and finally Behavioural Patterns.

The code can be found on GitHub.


Creational Patterns


A creational pattern abstracts the process of instantiating objects, decoupling a system from how its objects are represented and created.

There are five such patterns listed in the Gang of Four book. For each, I will:

  • briefly state the goal of the pattern (that is, what problem it is trying to solve);
  • show some minimal C# code using the pattern;
  • present some F# code solving the same problem; and
  • discuss the differences.

Quick links:


Abstract Factory


The goal:

This allows us to create families of related objects without specifying their concrete classes.

C# code:

using System;
namespace DesignPatterns
{
    public class UseAbstractFactoryPattern
    {
        public void Run ()
        {
            var printer = new ComponentInformationPrinter (new Type1Factory ());
            printer.PrintInformation ();
        }
    }

    public class ComponentInformationPrinter
    {
        public ComponentInformationPrinter (ComponentFactory componentFactory)
        {
            this.ComponentFactory = componentFactory;
        }

        private ComponentFactory ComponentFactory { get; }

        public void PrintInformation ()
        {
            var component = this.ComponentFactory.CreateComponent ();
            Console.WriteLine (component.Type ());
            Console.WriteLine (component.Category ());
        }
    }

    public abstract class ComponentFactory
    {
        public abstract Component CreateComponent ();
    }

    public abstract class Component
    {
        public abstract int Type ();
        public abstract string Category ();
    }

    public class Type1Component : Component
    {
        public override int Type () => 1;
        public override string Category () => "Category 1";
    }

    public class Type1Factory : ComponentFactory
    {
        public override Component CreateComponent () => new Type1Component ();
    }

    public class Type2Component : Component
    {
        public override int Type () => 2;
        public override string Category () => "Category 2";
    }

    public class Type2Factory : ComponentFactory
    {
        public override Component CreateComponent () => new Type2Component ();
    }
}

F# code:

module AbstractFactory

type Component = 
    | Type1Component
    | Type2Component

type ComponentFactory = 
    { Component : Component }

let getComponent (componentFactory : ComponentFactory) = componentFactory.Component

let getType = 
    function 
    | Type1Component -> 1
    | Type2Component -> 2

let getCategory = 
    function 
    | Type1Component -> "Category 1"
    | Type2Component -> "Category 2"

let printInformation componentFactory = 
    let componentInst = getComponent componentFactory
    printfn "%d" (getType componentInst)
    printfn "%s" (getCategory componentInst)

do printInformation { Component = Type1Component }

Discussion:

The code is more easily read if we distill it into the essence of what it is trying to achieve:

We want to specify the type of component we want, and in return be given a way to print information about the component.

In the C# version, this is done using inheritance and constructor injection: we create a ComponentInformationPrinter that accepts a ComponentFactory in its constructor, and then delegates to that factory to create the components which it then queries for their information. In turn, the components inherit from an abstract base class and provide their own implementation of the information-giving functions.

Whilst I could have made the F# code very similar (it does have classes, after all), the point of this post is to figure out what such patterns look like in a functional paradigm. Instead, I decided to use pattern matching functions to handle different types of components, which are defined using a discrimiated union.

This has the effect that, were we to add another type of component, we would need to update all of these functions to handle that particular case (or provide a degenerate catch-all case in the match function). Note that nothing on the factory side of things need be changed — in fact, the factory is simple a record type that wraps the underlying Component.

This is in stark contrast to the C# approach where we instead define a new class that inherits from Component, implement any required abstract functions, and then write a new factory class that inherits from ComponentFactory in order to get the new type back.

So which is better?

I think it really depends on the use case. The functional approach has the advantage that the factory definition is almost implicit, and we can define new factories on-the-fly. However, it has the disadvantage that we need to modify existing code to add a new type of Component.

This is unsuitable for (e.g.) distributing to third parties as a library, who will not then have the capability to extend the functionality. One way around this would be to define an interface with two methods, GetType and GetCategory, which clients could implement themsleves using object expressions.

On the whole, the patterns don’t look too dissimilar in a functional language, but I’m not sure the F# implementation really solves a real-world requirement in the same way that it does in C# — we could dispense with the factory altogether in F# and it wouldn’t really change anything from a caller’s perspective. I think the C# version is thus more of a ‘complete’ pattern.


Builder


The goal:

To make constructing a complex object independent of its representation, meaning that we can construct different representations via the same process.

C# code:

using System;
namespace DesignPatterns
{
    public class UseBuilderPattern
    {
        public void Run ()
        {
            var director = new ItemDirector ();

            var builder = new YellowItemBuilder ();

            director.Construct (builder);

            var builtItem = director.Construct (builder);

            builtItem.ShowParts ();
        }
    }

    public class ItemDirector
    {
        public Item Construct (ItemBuilder builder)
        {
            builder.BuildFirstPart ();
            builder.BuildSecondPart ();
            return builder.GetItem ();
        }
    }

    public abstract class ItemBuilder
    {
        public abstract void BuildFirstPart ();
        public abstract void BuildSecondPart ();
        public abstract Item GetItem ();
    }

    public class YellowItemBuilder : ItemBuilder
    {
        private readonly Item item = new Item ();

        public override void BuildFirstPart ()
        {
            item.FirstPartName = "YellowFirstPart";
        }

        public override void BuildSecondPart ()
        {
            item.SecondPartName = "YellowSecondPart";
        }

        public override Item GetItem () => item;
    }

    public class GreenItemBuilder : ItemBuilder
    {
        private readonly Item item = new Item ();

        public override void BuildFirstPart ()
        {
            item.FirstPartName = "GreenFirstPart";
        }

        public override void BuildSecondPart ()
        {
            item.SecondPartName = "GreenSecondPart";
        }

        public override Item GetItem () => item;
    }

    public class Item
    {
        public string FirstPartName;
        public string SecondPartName;

        public void ShowParts () => Console.WriteLine ($"{FirstPartName}, {SecondPartName}.");
    }
}

F# code:

module Builder

type Item = {mutable FirstPart : string; mutable SecondPart : string} 
    with member this.ShowParts() = sprintf "%s, %s." this.FirstPart this.SecondPart

type ItemBuilder =
    abstract member BuildFirstPart : unit->unit
    abstract member BuildSecondPart : unit->unit
    abstract member GetItem : unit -> Item
    abstract member item : Item

let yellowItemBuilder =  { new ItemBuilder with
      member this.item = {FirstPart = ""; SecondPart = ""}
      member this.BuildFirstPart() = this.item.FirstPart <- "YellowFirstPart"
      member this.BuildSecondPart() = this.item.FirstPart <- "YellowSecondPart"  
      member this.GetItem() = this.item }

let construct(builder:ItemBuilder) =
    builder.BuildFirstPart()
    builder.BuildSecondPart()
    builder.GetItem()

let run = 
    let item = construct yellowItemBuilder
    item.ShowParts()

Discussion:

The F# code took me an unreasonable amount of time to write, with lots of failed attempts to ‘make it more functional’ along the way. Diving into the literature, one suggested way to implement the Builder pattern in F# is to pass in a list of creation/processing functions to the director.

However, to me this is at odds with one of the main points of the pattern, that the director gets to choose the ordering of steps. If it takes a list of functions in, then the caller gets to choose the order.

Overall, I struggled to see how to solve this particular problem in a functional way. After all, the Builder pattern relies fundamentally on mutating things, which doesn’t sit nicely in the functional world.


Factory Method


The goal:

To allow subclasses to decide what type of class to instantiate.

This is a similar but subtly distinct goal from that of the Abstract Factory pattern above — to see the precise differences I am reusing the code from that example and showing only those sections that have changed.

C# code:

public class UseFactoryMethod
{
    public void Run ()
    {
        var printer = new ComponentInformationPrinter ();
        printer.PrintInformation ();
    }
}

public class ComponentInformationPrinter
{
    public virtual Component CreateComponent () =>  null;
    public void PrintInformation ()
    {
        var component = CreateComponent ();
        Console.WriteLine (component.Type ());
        Console.WriteLine (component.Category ());
    }
}

public class Type1Printer : ComponentInformationPrinter
{
    public override Component CreateComponent () => new Type1Component ();
}

public class Type2Printer : ComponentInformationPrinter
{
    public override Component CreateComponent () => new Type2Component ();
}

F# code:

let printInformation createComponent = 
    let componentInst = createComponent()
    printfn "%d" (getType componentInst)
    printfn "%s" (getCategory componentInst)

do printInformation (fun () -> Type1Component)

Discussion:

It should be clear from the code that this is really a subtle mutation of the Abstract Factory case which essentially gets rid of the factory class and moves the ‘hook’ into the ComponentInformationPrinter itself (i.e. to CreateComponent).

As such, the conclusions are much the same too — the patterns do broadly the same thing in both C# and F#.


Prototype

The goal:

To be able to create new objects by copying a prototypical instance.

C# code:

using System;
namespace DesignPatterns.Prototype
{
    public class UsePrototypes
    {
        public void Run ()
        {
            Component prototype = new Type1Component();
            var printer = new ComponentInformationPrinter (prototype);
            printer.PrintInformation ();
        }
    }

    public class ComponentInformationPrinter
    {
        public ComponentInformationPrinter (Component prototype)
        {
            this.prototype = prototype;
        }

        private Component prototype { get; }

        public void PrintInformation ()
        {
            var component = this.prototype.Clone ();
            Console.WriteLine (component.Type ());
            Console.WriteLine (component.Category ());
        }
    }

    public abstract class Component
    {
        public abstract int Type ();
        public abstract string Category ();
        public abstract Component Clone ();
    }

    public class Type1Component : Component
    {
        public override int Type () => 1;
        public override string Category () => "Category 1";
        public override Component Clone () => new Type1Component ();
    }

    public class Type2Component : Component
    {
        public override int Type () => 2;
        public override string Category () => "Category 2";
        public override Component Clone () => new Type1Component ();
    }
}

F# code:

let printInformation createComponent = 
    let componentInst = createComponent()
    printfn "%d" (getType componentInst)
    printfn "%s" (getCategory componentInst)

do printInformation (fun () -> Type1Component)

Discussion:

We can actually implement this pattern as another variation on the Abstract Factory pattern, this time injecting any required prototypes into the constructor of ComponentInformationPrinter and augmenting the Component class with a Clone() method.

In more complex examples of classes with data as well as behaviour, Clone() would have to decide exactly how much information to copy over (deep vs. shallow etc.), but here we simply have some baked-in behaviour that will transfer over.

The eagle-eyed amongst you will have noticed that the F# code is identical to that used for the Factory Method pattern. This is because the createComponent function was not only a factory method but also a prototype — this is because we were modelling Component as a discriminated union and so whatever we created was an immutable instance of that union.


Singleton


The goal:

Ensure that only one instance of a particular class can exist.

C# code:

public sealed class Singleton
{
    private static readonly Singleton instance = new Singleton ();

    static Singleton (){ }

    private Singleton () { }

    public static Singleton Instance => instance;
}

F# code:

type Singleton private() =
    static let instance = lazy(Singleton())
    static member Instance with get() = instance

Discussion:

The C# version looks deceptively simple. However, there are so many other versions of trying the same thing that run into problems with thread-safety, double locks, etc. that the pattern becomes slightly dangerous to use, especially for the less experienced developer.

I find it unlikely that someone who hasn’t written lots of singletons before will remember that they require static constructor so that the CLR marks the class as beforeFieldInit, and that deadlocking and performance are real possiblities, so to me this pattern doesn’t look ideal in C#.

On the other hand, the F# code is supposed to be less idiomatic, but actually looks better in my eyes thanks to static let bindings. It’s shorter and much clearer — we have a ‘thing’ (instance) and a way to get the one version of it that get ever exist, and that’s it!

Overall, this very common pattern is short & sweet in F#.


Conclusion & Next Time


Object creation looks quite different in C# and F#, and this flows through to the use of creational design patterns. As F# is an impure functional language, it has often felt like I have been using the less idiomatic parts of the language to write these object-oriented constructs. I suppose this is reassuring in a way — after all, the patterns were designed with OO in mind!

Next time we will look at Structural Patterns, and I expect there to be much bigger differences.