【问题标题】:Abstract factory: ways of realization抽象工厂:实现方式
【发布时间】:2018-10-31 09:27:55
【问题描述】:

我现在正在学习设计模式,并为每种模式阅读不同的资源。我有一个关于模式抽象工厂的问题。我读到了两种实现这一点的方法。我会用这个工厂来写,没有实现。例如,我制作了不同的门。

第一种方式。我们有门工厂的通用类,它包含用于制作不同类型门的不同方法(返回适当的门类):

$doorFactory = new DoorFactory();
$door1 = $doorFactory->createWoodDoor();

$doorFactory = new DoorFactory();
$door2 = $doorFactory->createSteelDoor();

第二种方式。我们有父类 DoorFactory 并扩展了 WoodDoorFactory 和 SteelDoorFactory 的类。该类实现相同的方法 createDoor(并返回适当的 Door 类)

$woodDoorFactory = new WoodDoorFactory();
$door1 = $woodDoorFactory->createDoor();

$steelDoorFactory = new SteelDoorFactory();
$door2 = $steelDoorFactory->createDoor();

你怎么看,哪种方式更优化和规范?

【问题讨论】:

    标签: oop design-patterns abstract-factory


    【解决方案1】:

    请想象一下您的工厂经过时的情况,而客户代码需要询问工厂的只是创建一扇门(不关心木材和钢材),您会明白为什么第二种方式更好。假设我们有一个类Client,其方法foo 使用工厂(我使用的是Java,但应该很容易理解):

    class Client {
        private DoorFactory factory;
        public Client(DoorFactory factory) { this.factory = factory; }
        public void foo() {
            Door door = factory.createDoor();
        }
    }
    

    现在您可以将WoodDoorFactory 或SteelDoorFactory 或WhateverDoorFactory 传递给Client 的构造函数。

    此外,更不用说您的第一种方式可能违反了The Single Responsibility Principles,因为DoorFactory 类知道许多可能无关的事情。事实上,它知道如何制作需要Wood APIs 的木门(只是示例),它知道如何制作需要Steel APIs 的钢制门。这显然减少了在另一个不想依赖Wood APIs 或Steel APIs 的环境中重用DoorFactory 类的机会。您的第二种方式不会发生此问题。

    【讨论】:

      【解决方案2】:

      与其他答案一样,我通常在实践中也更喜欢第二种方法。我发现它是一种更灵活、更有用的依赖注入方法。

      也就是说,我确实认为在某些情况下,第一种方法即使不是更好也同样有效——它们只是不那么常见。想到的一个例子是 XML 文档对象模型。如果您曾经使用过 Microsoft 的 c++ XML DOM Document API,那么您将熟悉这种方法(请参阅https://docs.microsoft.com/en-us/previous-versions/windows/desktop/ms760218(v%3dvs.85))

      在这种情况下,可以进入 XML 文档的定义明确的元素数量有限。也不需要能够动态扩展可以进入 XML 文档的元素类型——这一切都是由某些标准委员会预先确定的。因此,第一种工厂方法在这里适用,因为您可以从一开始就预先确定需要能够创建的所有不同类型的东西。

      在这种情况下,另一个优点是通过使 XML Document 类成为其中包含的所有元素的工厂,XML Document 可以完全控制这些内部对象的生命周期。注意:它们不允许在多个 XML 文档实例中使用相同的子元素。如果您想使用一个 XML 文档中的一个节点并将其放置在另一个 XML 文档中,您将需要通过第二个 XML 文档来生成一个新的节点元素以及任何和所有子元素的副本。

      在这种情况下,与 OP 中的示例的一个显着区别是,工厂方法不是用于提供创建相同类型事物的多种方法,而是工厂知道如何创建一堆高度相关的(和连接)对象类型。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-05-08
        • 1970-01-01
        • 2018-08-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-01-05
        • 1970-01-01
        相关资源
        最近更新 更多