Factory Pattern to build many derived classes

前端 未结 3 342
北海茫月
北海茫月 2021-02-03 12:14

I have a factory object ChallengeManager to generate instances of a Challenge object for a game I\'m building. There are many challenges. The constru

相关标签:
3条回答
  • 2021-02-03 12:40

    You're "decentralizing" the factory, such that each subclass is responsible for creating itself.

    More commonly you would have a central factory that would know about the possible subtypes and how to construct them (often enough, simply by creating a new instance and returning that instance typed as a common interface or common base class). That approach avoids the issue you currently have. I also see no benefit to your current approach. You are currently gaining no encapsulation or code reuse over the more typical implementation of a factory.

    For additional reference, have a look at

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

    0 讨论(0)
  • 2021-02-03 12:42

    I really like the pattern you are describing and use it often. The way I like to do it is:

    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 pattern has many nice properties. No one can make a new Challenge because it is abstract. No one can make a derived class because Challenge's default ctor is private. No one can get at ChallengeA or ChallengeB because they are private. You define the interface to Challenge and that is the only interface that the client needs to understand.

    When the client wants an A, they ask Challenge for one, and they get it. They don't need to worry about the fact that behind the scenes, A is implemented by ChallengeA. They just get a Challenge that they can use.

    0 讨论(0)
  • 2021-02-03 12:57

    Not necessarily the answer you are looking for but... You can use following implementation, if you can move away from static method per 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. e.g. 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{}
    
    0 讨论(0)
提交回复
热议问题