【问题标题】:Abstract Factory vs Factory method: Composition vs Inheritance? [duplicate]抽象工厂与工厂方法:组合与继承? [复制]
【发布时间】:2014-05-03 19:39:58
【问题描述】:

我看了很多关于抽象工厂和工厂方法之间区别的帖子,但是有一个我无法理解的问题。

两者之间的一个区别是抽象工厂 模式,一个类委托对象实例化的责任 通过组合到另一个对象,而工厂方法模式 使用继承并依赖子类来处理所需的对象 实例化

也许我知道为什么抽象工厂模式使用组合和委托来创建对象,但我不明白为什么工厂方法模式使用继承来创建具体的类对象。


这个问题不是关于什么是抽象工厂或什么是工厂方法,因此没有答案here

这是关于为什么当客户端也可以直接调用工厂方法时,工厂方法似乎使用继承。请取消标记为重复。

【问题讨论】:

    标签: design-patterns abstract-factory factory-method


    【解决方案1】:

    抽象工厂

    public interface IMyFactory
    {
        IMyClass CreateMyClass(int someParameter);
    }
    

    用法:

    public class SomeOtherClass
    {
        private readonly IMyFactory factory;
    
        public SomeOtherClass(IMyFactory factory)
        {
            this.factory = factory;
        }
    
        public void DoSomethingInteresting()
        {
            var mc = this.factory.CreateMyClass(42);
            // Do something interesting here
        }
    }
    

    请注意,SomeOtherClass 依赖于使用 IMyFactory 实例组合的 Composition。

    工厂方法

    public abstract class SomeOtherClassBase
    {
        public void DoSomethingInteresting()
        {
            var mc = this.CreateMyClass(42);
            // Do something interesting here
        }
    
        protected abstract IMyClass CreateMyClass(int someParameter)
    }
    

    用法:

    public class SomeOtherClass2 : SomeOtherClassBase
    {   
        protected override IMyClass CreateMyClass(int someParameter)
        {
            // Return an IMyClass instance from here
        }
    }
    

    请注意,此示例依赖于继承来工作。

    【讨论】:

    • 好的,我明白了,但哪种风格更好,哪些有优势?或者我们可以使用其中的任何一个?
    • 如果你喜欢组合而不是继承,你应该清楚你应该喜欢哪一个;)
    • @grep Abstract Factory 通常与产品系列一起使用,这意味着该接口对系列中的每个产品都有一个方法。此示例过度简化了具有单一产品系列的模式。即使它使用组合,抽象工厂也因为继承而存在风险。如果您需要在系列中添加(或删除)产品,则必须更改接口(添加或删除方法),从而更改所有工厂。如前所述,“组合优于继承”的好处并不是真正明显的区别。主要区别在于您是否拥有一系列产品。
    • @MarkSeemann 在你的工厂方法设计中,你假设客户端永远不会调用CreateMyClass(int someParameter),并且总是通过DoSomethingInteresting()间接调用它。为什么 ?因为如果它直接调用它,那么客户端也依赖对象组合来获取创建的对象。
    • @Number945 CreateMyClassprotected,所以客户端不能直接调用。
    猜你喜欢
    • 2014-01-14
    • 1970-01-01
    • 2011-05-11
    • 2020-10-25
    • 2011-01-05
    • 1970-01-01
    • 2022-01-19
    • 2012-03-26
    • 1970-01-01
    相关资源
    最近更新 更多