在产品类的接口或抽象超类中定义工厂方法

时间:2016-04-28 08:01:25

标签: c# inheritance interface factory-method

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

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

我可以以某种方式实现这一点,在接口或抽象超类方法定义之后使用静态工厂方法而不为每个单独的子类创建单独的静态工厂类吗?

3 个答案:

答案 0 :(得分: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)
    {}
}

答案 1 :(得分:0)

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

只需创建一个带有通用参数的简单工厂类,该参数指示要创建的内容。

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

}

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

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

答案 2 :(得分:0)

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

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方法以生成完美的克隆。现在人们可能会争辩说为什么抽象的克隆方法不能做同样的工作?是的,它可以。但是我需要克隆的子类实例以及一个空实例(没有从当前复制任何东西)所以我想出了这个架构。