Deze post is geïmporteerd van de oude blog en is nog niet geconverteerd naar de nieuwe syntax.
I present you with the next pattern in our series, the Factory Method! It took a while to get it out due to a stay in the hospital. (All is fine now :p)
The chapter I'm currently reading deals with both factory patterns, Factory Method and Abstract Factory, in one chapter, but I'm going to write an article on each to limit the length.
First of all, the definition: "Define an interface for creating an object, but let the subclasses decide which class to instantiate. The Factory method lets a class defer instantiation to subclasses."
Today we were given specs to add a building to our game. This building will create infantry units, set their behaviour to a specific setting and send them to a given waypoint after creation.
We start with a simplistic approach of creating an InfantryFactory class, which represents a building and contains a building-specific waypoint and unit behaviour setting to be given to new units.
It does the job, a specific unit is created based on a runtime parameter, it is given its behaviour and sent to a specific destination.
However, when we need to add new units, we need to open up this class every time again and change inside of it, which violates the Open/Closed Principle we talked about last time.
Let's isolate what changes and move it to its own method, just to illustrate we understand the part that is most subject to change.
Since the CreateUnit method is still inside the same class, we still have a problem. The BuildUnit method is a fine piece of code now however, it works with GameUnit objects instead of actual implementations.
Once this code passes our quality assurance it can be extended as much as wanted without having to modify it. Let's get this entire class to meet our quality standards now by implementing the Factory Method.
Our InfantryFactory class forms a nice base for creating units and performing various logic, let's lock it down for modification by making it abstract and throwing the CreateUnit implementation out as well.
To throw its implementation out, we are going to define CreateUnit as an abstract method, forcing subclasses to implement it. Let's create two factories for both our factions.
As you can see, I've taken the liberty to add some more units since last time, to illustrate how our two factories decide which class to instantiate in the CreateUnit method. Which is exactly what the Factory Method definition describes.
We defined an interface for creating an object, the abstract CreateUnit method, and let the subclasses, Barracks and HandOfNod, decide which class to instantiate. We made our InfantryFactory open for extension and closed for modification!
When we test this code, you can see our objects are always using abstract classes or interfaces (an abstract class is also called an interface sometimes, in the sense of the English language, not in the C# keyword).
The result after all this coding is this little output, and the fact that we learned another pattern, the Factory Method.
I've uploaded the solution again. If you have any questions or feedback, please comment.
Some additional information on the Factory Method pattern:
The chapter I'm currently reading deals with both factory patterns, Factory Method and Abstract Factory, in one chapter, but I'm going to write an article on each to limit the length.
First of all, the definition: "Define an interface for creating an object, but let the subclasses decide which class to instantiate. The Factory method lets a class defer instantiation to subclasses."
Today we were given specs to add a building to our game. This building will create infantry units, set their behaviour to a specific setting and send them to a given waypoint after creation.
We start with a simplistic approach of creating an InfantryFactory class, which represents a building and contains a building-specific waypoint and unit behaviour setting to be given to new units.
It does the job, a specific unit is created based on a runtime parameter, it is given its behaviour and sent to a specific destination.
However, when we need to add new units, we need to open up this class every time again and change inside of it, which violates the Open/Closed Principle we talked about last time.
Let's isolate what changes and move it to its own method, just to illustrate we understand the part that is most subject to change.
Since the CreateUnit method is still inside the same class, we still have a problem. The BuildUnit method is a fine piece of code now however, it works with GameUnit objects instead of actual implementations.
Once this code passes our quality assurance it can be extended as much as wanted without having to modify it. Let's get this entire class to meet our quality standards now by implementing the Factory Method.
Our InfantryFactory class forms a nice base for creating units and performing various logic, let's lock it down for modification by making it abstract and throwing the CreateUnit implementation out as well.
To throw its implementation out, we are going to define CreateUnit as an abstract method, forcing subclasses to implement it. Let's create two factories for both our factions.
As you can see, I've taken the liberty to add some more units since last time, to illustrate how our two factories decide which class to instantiate in the CreateUnit method. Which is exactly what the Factory Method definition describes.
We defined an interface for creating an object, the abstract CreateUnit method, and let the subclasses, Barracks and HandOfNod, decide which class to instantiate. We made our InfantryFactory open for extension and closed for modification!
When we test this code, you can see our objects are always using abstract classes or interfaces (an abstract class is also called an interface sometimes, in the sense of the English language, not in the C# keyword).
The result after all this coding is this little output, and the fact that we learned another pattern, the Factory Method.
I've uploaded the solution again. If you have any questions or feedback, please comment.
Some additional information on the Factory Method pattern:
Thank you again!
I'm happy that everything is doing fine now!
I was hoping for another blog post :)
Thank you
You have great screens with examples. What tool are You using?
P.S.
Article is great too.
I'm using Visual Studio 2008 built-in class diagram support :)
We thank you but try Java!
I tried Java :) Everyone's free to code in whatever language he likes, and whatever IDE, I'm not a zealot of any kind :)
thanks for your greate article,
there's a thing that has got me thinkin tho'...
if we added a new type of unit, we had to modify the subclasses of InfrantryFactory (adding a new case: ..) so why is it such a big advantage that we have to modify those and not InfrantryFactory itself? dont we violate the closed for modification/open for extension principle in either way?
hope i could make my problem clear, keep up the great work + thanks in advance!
In the end you'll always have to change something somewhere when adding new classes.
What we have done, is moved to responsibility of how a GameUnit is created, to another class.
In the case of this example, a case is used to create new objects. But nobody says this has to be. It could very well be that a particular subclass always creates just one type of GameUnit, or that it creates type A with a lot of different parameters than B.
The logic on how to create a GameUnit is splitted from the class responsible for creating soldiers. The rest of our codebase will work with an InfantryFactory, which is locked (closed for modification), but have an actual implementation inside it (open for extension)
eg:
InfrantryFactory a = SomeClass.GetInfantryFactory(Faction.NOD);
Want a new faction? Create a new subclass, but don't touch anything else in your code (except the line above ofcourse, to assign your subclass :p)
your article is easily to be understood
thanks for your sharing
Does Visual Studio 2005 support built-in class diagram?