简体   繁体   English

C#工厂模式新手

[英]C# Factory Pattern newbie

I've been reading everything I can find about Factory/Abstract Factory/Simple Factory/etc. 我一直在阅读关于Factory / Abstract Factory / Simple Factory / etc的所有资料。 I've been unable to find an answer to this question. 我一直找不到这个问题的答案。 I understand the classes the factory creates must implement the same interface, or derive from the same base class. 我了解工厂创建的类必须实现相同的接口,或从相同的基类派生。 But what happens if the different classes don't end up with the same public interface? 但是,如果不同的类不以相同的公共接口结尾怎么办? IE SubClass1 and SubClass2 both derive from BaseClass. IE SubClass1和SubClass2都派生自BaseClass。 Now SubClass1 adds PropertyA, and SubClass2 adds PropertyB. 现在,SubClass1 添加了 PropertyA,SubClass2添加了PropertyB。 Am I correct in assuming these classes can't be created by a factory, since they don't have the same interface? 我在假设这些类不能由工厂创建,因为它们不具有相同的接口是否正确? Or, if they were created as BaseClass, they wouldn't expose their new properties. 或者,如果它们是作为BaseClass创建的,则它们不会公开其新属性。 The same problem exists with a common interface. 通用接口也存在相同的问题。 And if anyone knows an author that addresses this, I'd appreciate a reference. 如果有人认识到解决这个问题的作者,我将不胜感激。

Thanks so much! 非常感谢!

I think you have missed the purpose of an interface. 我认为您已经错过了界面的目的。 If you are using interfaces it may not be best practice to create classes the have public methods which are not part of an interface. 如果使用接口,则最好不要创建具有公共方法的类,这些类不是接口的一部分。

So if your factory produces IAnimal. 因此,如果您的工厂生产IAnimal。 You should not assume you are getting a Dog class that implements a WagTail method, or a Cat class that LandsOnFeet. 您不应该假设自己正在获得实现WagTail方法的Dog类,或获得LandsOnFeet的Cat类。 You need to define IDog and ICat. 您需要定义IDog和ICat。 (Possibly inheriting from IAnimal). (可能从IAnimal继承)。

You then can consider how your factory behaves. 然后,您可以考虑工厂的行为方式。 You have a couple of options. 您有两种选择。

A. Generics A.泛型

You could then create a Generic Factory interface IAnimalFactory which when implemented returns either an IAnimal or the specific type. 然后,您可以创建Generic Factory接口IAnimalFactory,该接口在实现时将返回IAnimal或特定类型。

public interface IAnimal
    {
        int Legs();
    }

public interface IAnimalFactory<T> where T: IAnimal 
{
    IAnimal CreateAnimal();
    T CreateSpecificAnimal();
}

public interface IDog:IAnimal 
{
    void WagTail();
}

public interface ICat : IAnimal
{
    void LandOnFeet();
}

public class Dog:IDog
{
//Implementation Excluded
}

public class Cat : ICat
{
 //Implementation Excluded
}

public class DogFactory:IAnimalFactory<IDog>
{
    public IAnimal CreateAnimal()
    {
        return (IAnimal)CreateSpecificAnimal();
    }

    public IDog CreateSpecificAnimal()
    {
        return new Dog();
    }

}

public class CatFactory : IAnimalFactory<ICat>
{
    public IAnimal CreateAnimal()
    {
        return (IAnimal)CreateSpecificAnimal();
    }

    public ICat CreateSpecificAnimal()
    {
        return new Cat();
    }

}

The Generic approach gives you some future proofing if you then decide to implement IDomesticDog or IWildDog, and is my preference, but may be more complex then necessary depending on your needs. 如果您随后决定实施IDomesticDog或IWildDog,则通用方法可为您提供一些将来的证明,这是我的偏爱,但根据您的需要,它可能比需要的更为复杂。

B. Specific Methods per SubClass B.每个子类的特定方法

You could also create a factory that has functions which create a dog or cat of type IAnimal. 您也可以创建一个具有功能的工厂,该功能可以创建IAnimal类型的狗或猫。

public class AnimalFactory
    {
        public IAnimal GetDog()
        {
            return (IAnimal) new Dog();
        }

        public IAnimal GetCat()
        {
            return (IAnimal) new Cat();
        }

    }

Now as advised above you can safely cast to IDog or ICat. 现在,按照上面的建议,您可以安全地投射到IDog或ICat。

I don't think there is one author that will specifically answer your question. 我认为没有一位作者会专门回答您的问题。 However reading about Inversion of Control and Dependency Injection will likely give you the right level of information you need. 但是,有关控制反转和依赖注入的阅读可能会为您提供所需的正确信息级别。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM