【问题标题】:Defining factory methods in interfaces or abstract superclasses of the product class在产品类的接口或抽象超类中定义工厂方法
【发布时间】:2016-04-28 08:01:25
【问题描述】:

我有一个抽象的超类和继承自它的子类。

每个子类MySubclass 都应该有一个public static MySubclass CreateFrom(ISomething something) 工厂方法。其参数的接口对于所有子类都是相同的,但返回类型当然必须始终是相应子类的类型。

我能否以某种方式实现这一点,让静态工厂方法遵循接口或抽象超类方法定义,而无需为每个子类创建单独的静态工厂类?

【问题讨论】:

    标签: c# inheritance interface factory-method


    【解决方案1】:

    如果 ISomething 始终是相同(或至少是通用)类型,您可以将超类的 CreateFrom 方法设为泛型,并使用参数调用继承类的构造函数。只需确保所有继承的类都具有该构造函数(不确定,但我认为没有办法“强制”构造函数模式)。

    public abstract class SuperClass
    {
        public static T CreateFrom(ISomething something)
        {
            return (T)Activator.CreateInstance(typeof(T), something);
        }
    }
    
    public class InheritedClass : SuperClass
    {
        public InheritedClass(ISomething something)
        {}
    }
    

    这样你可以通过调用来创建实例

    SuperClass.CreateFrom<InheritedClass>(something);
    

    或者你拆分创建和初始化:

    public abstract class SuperClass
    {
        protected abstract void Initialize(ISomething something);
    
        public static T CreateFrom(ISomething something) where T : new()
        {
            T result = new T();
            T.Initialize(something);
        }
    }
    
    public class InheritedClass : SuperClass
    {
        public InheritedClass()
        {}
    
        protected override Initialize(ISomething something)
        {}
    }
    

    【讨论】:

      【解决方案2】:

      您不能在接口上定义静态成员,因为静态成员属于某个类。但是我无法想象使用它的理由。您应该问自己为什么需要这样的功能。子类是否真的必须实例化自己,或者可以很容易地用另一个独立的(工厂)类来完成?

      只需创建一个简单的工厂类,并使用一个通用参数来指示要创建的内容。

      class Factory<T> where T: new()
      {
          T CreateFrom(ISomething param)
          {
              return new T();
          }
      
      }
      

      现在你可以简单地这样称呼它:

      var myFactory = new Factory<MyClass>();
      myFactory.CreateFrom(mySomething);
      

      【讨论】:

      • 这需要子类的实例,因为 CreateFrom 方法不是静态的。我认为这正是他想要避免的。
      【解决方案3】:

      我在类似的需求中采用了不同的解决方案。在我碰巧是一个抽象的超类中,我需要创建一个子类的实例来处理它,所以我做了以下技巧:

      public abstract class Element
      {
          protected virtual void copyFrom(Element other)
          {  
          }
      
          protected abstract Elememt newInstanceOfMyType();
          public object clone()
          {
              var instance= newInstanceOfMyType();
              instance.copyFrom(this);
              return instance;        
          }
      }
      

      现在我所有从 Element 类继承的子类都需要重写 newInstanceOfMyType 方法以放弃其类型的实例,然后还重写 copyFrom 方法以生成完美的克隆。现在人们可能会争辩说,为什么抽象的 Clone 方法不能做同样的工作?是的,它可以。但是我需要子类的克隆实例以及一个空实例(不从当前复制任何内容),所以我想出了这个架构。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2021-04-09
        • 2017-10-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多