I've been doing some reading about design patterns and wanted some perspective. Consider the following:
Dim objGruntWorker as IGruntWorker
if SomeCriteria then
objGruntWorker = new GoFor()
else if SomeOtherCriteria then
objGruntWorker = new Newb()
else if SomeCriteriaAndTheKitchenSink then
objGruntWorker = new CubeRat()
end if
objGruntWorker.GetBreakfast()
system.threading.thread.sleep(GetMilliSecondsFromHours(4))
objGruntWorker.GetLunch()
The above code grows each time a new Criteria arises. I've seen code like this all over the place and in ignorance wrote some of it myself. How should this be solved? Does this kind of anti-pattern have a more "formal" name? Thanks for your help!
Edit: Another consideration is I want to avoid having to recompile the existing implementations of IGruntWorker
simply to add a new implementation.
That sort of logic is often encapsulated using the Factory method pattern. (See the ImageReaderFactory example under Encapsulation.)
The type of pattern that would suit the above solution would be the Factory Pattern. You have a situation where you don't need to know the concrete type of object you require, it just has to implement IGruntWorker
. So you create a factory which takes in a criteria and based on that criteria you would return the specific IGruntWorker
object. It is usually a good idea to map the criteria to some identifier i.e. an enumeration or constant for readability e.g.
public enum WorkerType
{
Newbie,
Average,
Expert
}
public class WorkerFactory
{
public static IGruntWorker GetWorker(WorkerType type)
{
switch (type)
{
case WorkerType.Newbie:
return new NewbieWorker();
case WorkerType.Average:
return new AverageWorker();
case WorkerType.Expert:
return new ExpertWorker();
}
}
}
So in your case you could have a small helper method that works out the correct type of Worker required based on the criteria. This could even be wrapped up in a read-only property which you just pass into the factory.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With