Fluent interface for factory to create hierarchy of objects

Fluent interfaces are great for a various amount of situations because they permit to create a simple DSL using only the base capabilities of your language of choice. I like very much Fluent Interfaces especially to create Factories to avoid messing with several constructors when your classes are complex to create.

The model

Suppose you want to create a fluent Factory for a * Character *abstract class that has two concrete classes called: Warriors and Wizards, with this model you want to create a Fluent Interface to create object. This is the Class Diagram

image

Figure 1: Class diagram for Warriors and Wizards

Now I hear you screaming that I’ve just blogged about Getter properties as an Antipattern, but clearly there are a lot of situations where we can live happily with public getters, because we should not think that a “single technique fits all of my models” really exists, so I need to be aware that sometimes you can have public getter and sometimes even public setter and the purpose of a fluent factory class is to permit the creation of a class with a clear syntax and with full intellisense suggestions.

The problem If you want to create a Fluent interface, you should be aware that warrior and wizard have specific properties, like ArmorProtectionLevel for Warriors, that are not available to the other class, but a lot of properties are shared in the base class and are available to both of them.

To avoid duplication I want to be able to create a base fluent factory for base properties, then specialize a specific factory for each concrete class, specifying only the methods to fill specific properties of objects. In the end I want to be able to write this code.

image

Figure 2: Code to create a warrior with fluent factory

Since I want to be able to fully use the intellisense, the CharacterFactory for warrior should permit me to set only properties available to warriors.

image

Figure 3: Intellisense suggests me both the WithArmorProtectionLEvel and the base class WithHealth methods.

As you can see, the methods that intellisense is suggesting are Extension Methods and this is the trick that permits to easily create a factory that supports inheritance. In this situation the WithHealth factory method should be available to Wizard and Warriors (health is a property of the base class), but WithArmorProtectionLevel() should be available only for Warrior factories. Suppose to create a basic CharacterFactory class and two inherited factory class, do you see the problem?

Implementing the Health setter method in the base Character Factory class is not trivial because you really do not know the return type. If such a method method would return a CharacterFactory class you will lose all the methods for Warriors and Wizards properties. This makes inheritance not suitable to create a good implementation of factory classes for a hierarchy of objects.

A trivial and not-so-good solution is to delegate all factory methods to concrete WarriorFactory and WizardFactory,  with this solution the WithHealth() method will be implemented both in Warrior Factory and in Wizard Factory and each one can return the correct type. This will lead to a lot of duplicated code, because each concrete factory should be able to set all properties, and for complex hierarchy can be a mess to maintain.

The solution

The solution is using Extension Methods plus generics to make compile do all the magic for us, this is the code for the base factory for Character class

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
 
public class CharacterFactory
{
private static Character _model = null;
 
public static WarriorFactory Warrior(String name)
{
var factory = new WarriorFactory();
factory._state.Set(() => _model.Name, name);
return factory;
}
 
public static WizardFactory Wizard(string name)
{
var factory = new WizardFactory();
factory._state.Set(() => _model.Name, name);
return factory;
}
 
internal State _state = new State();
}

As you can see the factory actually has only static methods to generate the right factory for each concrete class. To set properties the base factory stores a static instance of a Character class called _model, that is used to do static reflection when you need to set a property into the real state object of the class, stored in the _state variable.

As you can see for WarriorFactory construction method, in the line 8 we construct a new WarriorFactory, in line 9 the factory sets the name of the character using static reflection in the state object of the concrete factory and finally the real factory is returned.

Now the problem is, where is the WithHealth() method to set the Health of a generic Charatcer? To solve the aforementioned problem you should implement all the factory methods that logically belongs to base class with generic Extension Methods.

1
2
3
4
5
6
7
8
9
public static class CharacterFactoryMethods
{
private static Character _model = null;
public static T WithHealth<T>(this T fluent, Int32 healthValue) where T : CharacterFactory
{
fluent._state.Set(() => _model.Health, healthValue);
return fluent;
}
}

The trick is to define this extension method generic on type T, then restrict T to be a class that inherit from CharacterFactory and return a value of type T. With this code, if you create a WarriorFactory (that inherits from CharacterFactory) the compiler permits you to call this extension method binding the type T to WarriorFactory; this means that when you call WithHealth on WarriorFactory it will return a WarriorFactory, but when you call on a WizardFactory it will return a WizardFactory, so the chaining is not broken. Now I can write this code.

1
2
3
4
Warrior warrior2 = CharacterFactory.Warrior("Frodo")
.WithHealth(50)
.WithArmorProtectionLevel(5)
.Create();

If you look closely to the order of method call, you can see that you first call the WithHealth method that logically belongs to the base CharacterFactory class, but then you are still able to call specific WarriorFactory methods, with full intellisense support.

image

Figure 4: Even after the call of a method of the factory for base class, I’m still able to call warrior specific methods.

Now if you are curious how is implemented the specific WarriorFactory class here is the code.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
public class WarriorFactory : CharacterFactory
{
private static Warrior _model = null;
 
public Warrior Create()
{
return new Warrior(_state);
}
}
 
public static class WarriorFactoryMethods
{
private static Warrior _model = null;
public static T WithArmorProtectionLevel<T>(this T fluent, Int32 armorProtectionlevel) where T : WarriorFactory
{
fluent._state.Set(() => _model.ArmorProtectionLevel, armorProtectionlevel);
return fluent;
}
}

The real class contains only the Create() method, that is responsible to create the object passing the _state object with all the properties populated by factory method calls, then the WithArmorProtectionLevel is implemented as extension method of a generic T class with T : WarriorFactory restriction. This is the same trick used with the base factory class and now you are able to create efficient factories for hierarchy of objects with little code.

Here is the class diagram of the three factories

image

And that’s all folks.

Gian Maria.