Factory Template for building many derived classes

I have a factory ChallengeManager object to generate instances of the Challenge object for the game I am creating. There are a lot of problems. The constructors for each output of the Challenge class are different, but there is a common interface between them defined in the base class.

When I call manager.CreateChallenge() , it returns an instance of Challenge , which is one of the derived types.

Ideally, I would like to save the code for building the object inside the derived class itself, so all the code associated with this object is located together. Example:

 class Challenge {} class ChallengeA : Challenge { public static Challenge MakeChallenge() { return new ChallengeA(); } } class ChallengeB : Challenge { public static Challenge MakeChallenge() { return new ChallengeB(); } } 

Now my ChallengeManager.CreateChallenge() call should only be solved by the class to call MakeChallenge() on. The implementation of the construction is contained in the class itself.

Using this paradigm, each derived class must define a static MakeChallenge() method. However, since the method is static, I cannot use the interface here, requiring it.

This is not a big deal, as I can easily add the correct method signature for each derived class. However, I am wondering if there is a more elegant design that I should consider.

+7
c # design-patterns factory-pattern
source share
3 answers

I really like the template that you describe and use it often. I like to do this:

 abstract class Challenge { private Challenge() {} private class ChallengeA : Challenge { public ChallengeA() { ... } } private class ChallengeB : Challenge { public ChallengeB() { ... } } public static Challenge MakeA() { return new ChallengeA(); } public static Challenge MakeB() { return new ChallengeB(); } } 

This template has many good properties. No one can create a new Challenge because it is abstract. No one can create a derived class because the Challenge default ctor is private. No one can get into ChallengeA or ChallengeB because they are private. You define the interface with the Challenge , and this is the only interface that the client must understand.

When a client wants A , they ask for a Challenge for one, and they get it. They don’t need to worry that ChallengeA is being implemented behind the scenes of A They just get a Challenge that they can use.

+21
source share

You "decentralize" the factory, so each subclass is responsible for the creation itself.

Most often, you will have a central factory that will know about the possible subtypes and how to create them (quite often, just creating a new instance and returning this instance, typed as a common interface or a common base class). This approach avoids the problem that you currently have. I also do not see any benefit from your current approach. Currently you are not getting encapsulation or code reuse of a more typical factory implementation.

For more help see

http://www.oodesign.com/factory-pattern.html

+2
source share

Not necessarily the answer you are looking for, but ... You can use the following implementation if you can move away from the static method for each class.

 using System; public class Test { public static void Main() { var c1 = ChallengeManager.CreateChallenge(); var c2 = ChallengeManager.CreateChallenge(); //var c = ChallengeManager.CreateChallenge<Challenage>(); // This statement won't compile } } public class ChallengeManager { public static Challenage CreateChallenge() { // identify which challenge to instantiate. eg Challenage1 var c = CreateChallenge<Challenage1>(); return c; } private static Challenage CreateChallenge<T>() where T: Challenage, new() { return new T(); } } public abstract class Challenage{} public class Challenage1: Challenage{} public class Challenage2: Challenage{} 
+1
source share

All Articles