简体   繁体   English

使用工厂方法模式比简单工厂有什么优势?

[英]what's the advantage of using factory method pattern over simple factory?

I am reading about factory method pattern and simple factory.我正在阅读有关工厂方法模式和简单工厂的信息。 turns out As I can understand, simple factory is enough and I don't see the use case of factory method pattern.结果据我所知,简单的工厂就足够了,我没有看到工厂方法模式的用例。 Please read this link, https://www.binpress.com/factory-design-pattern/ , and I'll ask my questions.请阅读此链接https://www.binpress.com/factory-design-pattern/ ,我会问我的问题。

1) in simple factory , it says it's bad because it violates the open/closed principle. 1) 在 simple factory 中,它说它不好,因为它违反了开放/封闭原则。 I understand that but in factory method pattern what it did still violates the open/closed principle.我明白这一点,但在工厂方法模式中,它所做的仍然违反了开放/封闭原则。

if ('car'==$toyName) {
            $toy = new NyCar();
        } else if ('helicopter'==$toyName) {
            $toy = new NyHelicopter();
        }

If there'll be a new tory for New York, we need to add it here.如果纽约有新的保守党,我们需要在这里添加。

2) after reading the link, before it actually reached the better solution, it used this following code. 2)阅读链接后,在实际达到更好的解决方案之前,它使用了以下代码。 :

class NySimpleFactory {
    public function createToy($toyName) {
        $toy = null;

        if ('car'==$toyName) {
            $toy = new NyCar();
        } else if ('helicopter'==$toyName) {
            $toy = new NyHelicopter();
        }

        return $toy;
    }
}

class NyToysFactory {

    public $simpleFactory;

    public function __construct(SimpleFactory $simpleFactory) {
        $this->simpleFactory = $simpleFactory;
    }

    public function produceToy($toyName) {
        $toy = null;
        $toy = $this->simpleFactory->createToy($toyName);
        $toy->prepare();
        $toy->package();
        $toy->label();
        return $toy;
    }
}

Then it says,然后它说,

The developers finish the new code quickly and hand it over to the US factories.开发人员很快完成了新代码,并将其交给了美国工厂。 After two weeks, the phone starts ringing in the developers' office because the New York factory was having production issues.两周后,由于纽约工厂的生产出现问题,开发商办公室的电话开始响起。 It turns out that the NyToysFactory class has been modified by developers at the remote branch because the staff doesn't want to do packaging and labeling work.原来 NyToysFactory 类已经被远程分支的开发人员修改了,因为工作人员不想做打包和标签工作。 They've modified produceToy() by removing its label() and package() functions.他们通过删除 label() 和 package() 函数修改了produceToy()。

It seems like Simple Factory won't work in this scenario.在这种情况下,Simple Factory 似乎不起作用。 We don't want branches in US to be able to modify produceToy() functions.我们不希望美国的分支机构能够修改produceToy() 函数。 ProduceToy() should consist of a set of standard procedures and the branches should only be responsible for creating location specific toys. ProduceToy() 应该由一组标准程序组成,分支应该只负责创建特定于位置的玩具。 What if they can create an abstract class?如果他们可以创建一个抽象类呢? And the abstract class they create will have a concrete produceToy()method which will implement a set of standard operating procedurea that all branches have to follow.他们创建的抽象类将有一个具体的produceToy()方法,该方法将实现一组所有分支都必须遵循的标准操作程序。 Inside produceToy(), it calls its own abstract method createToy() to obtain a toy class.在produceToy()内部,它调用自己的抽象方法createToy()来获取玩具类。 This way createToy() is able to encapsulate object creation and, since it's abstract, it delegates the creation to its subclasses.通过这种方式 createToy() 能够封装对象创建,并且由于它是抽象的,因此它将创建委托给其子类。

Question is: a)What does it mean by saying handing over it to US factories?问题是: a) 说把它交给美国工厂是什么意思? b) or We don't want branches in US to be able to modify produceToy() functions. b) 或者我们不希望美国的分支机构能够修改produceToy() 函数。 they can still modify produceToy function, what difference does it make at all if they can't or can change it?他们仍然可以修改produceToy函数,如果他们不能或可以改变它有什么区别? I just don't understand why simple factory was bad for the following example at all.我只是不明白为什么简单工厂对以下示例不利。

No need to read about abstract factory at that link无需在该链接上阅读有关抽象工厂的信息

T HIS CODE / PROBLEM does not illuminate the Abstract Factory or Factory Method. Ť他的代码/问题不照亮抽象工厂或工厂方法。 Deciding which class to instantiate by switching on a parameter is indeed an anti-pattern encouraging open-closed principle violation.通过打开参数来决定实例化哪个类确实是一种鼓励违反开闭原则的反模式。

Abstract Factory抽象工厂

The Abstract Factory is all about enforcing a family of related classes:抽象工厂是所有关于强制执行家庭相关的类:

abstract class ToyFactory
+ createBear(): ToyBear
+ createElephant(): ToyElephant

class USToyFactory extends ToyFactory
+ createBear(): ToyBear -> creates USToyBear
+ createElephant(): ToyElephant -> USToyElephant

abstract class ToyBear
+ playSound()

class USToyBear extends ToyBear
+ playSound()//play US National Anthem

Passing a USToyFactory where a ToyFactory is expected enforces the creation of US toys (USToyBear and USToyElephant) – this is the power of Abstract Factory.传递一个 USToyFactory 来强制创建美国玩具(USToyBear 和 USToyElephant)——这就是抽象工厂的力量。

Notice the products , bears, elephants, etc., are known AoT (ahead of time).请注意,产品、熊、大象等是已知的 AoT(提前)。

Factory Method工厂方法

The Factory Method is all about deferring instantiation to subclasses.工厂方法就是将实例化推迟到子类。

abstract class Dashboard
+ createWidget(): Widget

abstract class Widget
+ config()

class StatsDashboard extends Dashboard
+ createWidget: Widget -> return new StatsWidget()

class StatsWidget extends Widget

Calling createWidget() returns a Widget, but which concrete Widget to return must be deferred to subclasses (StatsDashboard returns a StatsWidget).调用 createWidget() 返回一个 Widget,但是返回哪个具体的 Widget 必须推迟到子类(StatsDashboard 返回一个 StatsWidget)。

Notice the creation methods are declared up the inheritance tree, but they are fulfilled down the inheritance tree.请注意,创建方法在继承树上声明,但它们在继承树下实现。

❧ A reader with a keen eye will see that Abstract Factory methods resemble Factory Methods, coincidence? ❧ 敏锐的读者会发现抽象工厂方法类似于工厂方法,巧合吗? – no. - 不。 This is where Factory Method's name is derived (they fulfill concrete class instantiation).这是派生工厂方法名称的地方(它们实现了具体的类实例化)。

The confusion regarding “US factories” is valid;关于“美国工厂”的混淆是有道理的; this is poor word choice.这是一个糟糕的词选择。 The author hints this code may be passed around to factory workers which is totally irrelevant and confusing pertaining to the factory patterns.作者暗示此代码可能会传递给工厂工人,这与工厂模式完全无关且令人困惑。


To resolve the switch above, you'll need to realize the obvious: each condition handler is related in some way.要解决上面的切换,您需要意识到显而易见的事情:每个条件处理程序都以某种方式相关。 In this case, they are all toys.在这种情况下,它们都是玩具。

public function createToy($toyName) {
    $toy = null;

    if ('car'==$toyName) {
        $toy = new NyCar();//I'm a Toy
    } else if ('helicopter'==$toyName) {
        $toy = new NyHelicopter();//I'm a Toy
    }

    return $toy;
}

Using polymorphism, we can satisfy the open-closed principle by creating a set of sibling classes:使用多态,我们可以通过创建一组兄弟类来满足开闭原则:

abstract class Toy
+ operate()

Car extends Toy

Helicopter extends Toy

some_toy.operate();

Adding to the switch cases is nothing more than creating another sibling class.添加到 switch case 无非是创建另一个兄弟类。

I hope this helps!我希望这有帮助!

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

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