In the previous article, we explored the theory of the builder pattern.
Let’s see a more concrete example :
Let’s assuming that we are building a Role Playing Game core model. Here are the basic rules:
- A player can be a Hero : a Warrior, a Wizard, or a Thief (we keep it simple)
- Every Hero has 4 main characteristics: Health, Strength, Spirit, and Speed, that are counted in points.
- Heroes have a Level, and starting characteristics are based on this level (Health starts at Level * 10, Strength and Spirit start at Level * 5, and Speed starts at Level * 3)
- Warrior has a (+2 Strength, -2 Spirit) Modificator, Wizard has (+2 Spirit, -2 Strength) Modificator
- Player can improve 2 Characteristics of 1 points each or 1 characteristic of 2 points, in order to cutomize his Hero.
A naive implementation of the Hero class would be :
Let’s focus on the Hero Creation : Every Heroes are of the same kind : Indeed, despite of the different classes, every Hero has the same kind of characteristics. So, there is no need for a specific class reflecting the “Hero Class”.
We want to be sure that our builder can build a warrior. So the implementation is straigth-forward :
Obviously, we can add the methods for the other classes (keep in mind that the scope is really thin).
Next step would be to ensure we cannot build a Hero without a class. The test would be :
So we update the Builder accordingly :
The guard occurs in the Create Method because it’s the most convenient place to place it, for the moment.
By following our “Business Rules”, we end-up with this kind of class :
We actually built a Domain-Specific-Language for our Hero Creation Context. This could seem a bit complex for the purpose at the first sight, but we do acheive a complete separation between the complexity of building a Hero and the behavior of the Hero later in the game. To illustrate this, we can take a look to a potential implementation of a game client :
In this article, we saw how to implement the Builder Design Pattern in C# in a Fluent Interface way.
You can find the source code in this github repository