与简单工厂相比,使用工厂方法模式有什么优势? [英] what's the advantage of using factory method pattern over simple factory?

查看:83
本文介绍了与简单工厂相比,使用工厂方法模式有什么优势?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在阅读有关工厂方法模式和简单工厂的信息.事实证明,简单的工厂就足够了,而且我看不到工厂方法模式的用例.请阅读此链接, https://www.binpress.com/factory-design-pattern/,我会问我的问题.

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.

1)在简单工厂中,它说这很不好,因为它违反了打开/关闭原则.我知道,但是在工厂方法模式中,它仍然违反了打开/关闭的原则.

1) in simple factory , it says it's bad because it violates the open/closed principle. 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)在阅读链接之后,在实际达到更好的解决方案之前,它使用了以下代码.:

2) after reading the link, before it actually reached the better solution, it used this following code. :

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;
    }
}

然后说,

开发人员快速完成新代码并将其移交给美国工厂.两周后,手机开始响起开发人员办公室,因为纽约工厂正在生产问题.原来NyToysFactory类已被修改远程分支机构的开发人员,因为员工不想做包装和标签工作.他们通过删除来修改了ProduceToy()其label()和package()函数.

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. They’ve modified produceToy() by removing its label() and package() functions.

在这种情况下,简单工厂似乎无法正常工作.我们不希望美国的分支机构能够修改ProduceToy()函数.ProduceToy()应包含一组标准过程,并且分支机构仅应负责创建特定于位置的信息玩具.如果他们可以创建一个抽象类怎么办?和抽象他们创建的类将具有具体的produceToy()方法,该方法将实施所有分支机构的一套标准操作程序必须遵循.在ProduceToy()内部,它调用自己的抽象方法createToy()获取玩具类.这样createToy()能够封装对象创建,并且由于它是抽象的,因此将创建到其子类.

It seems like Simple Factory won’t work in this scenario. We don’t want branches in US to be able to modify produceToy() functions. ProduceToy() should consist of a set of standard procedures and the branches should only be responsible for creating location specific toys. 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. Inside produceToy(), it calls its own abstract method createToy() to obtain a toy class. This way createToy() is able to encapsulate object creation and, since it’s abstract, it delegates the creation to its subclasses.

问题是:a)说将其移交给美国工厂意味着什么?b)或我们不希望美国的分支机构能够修改ProduceToy()函数.他们仍然可以修改ProduceToy函数,如果他们不能或者可以改变它,那有什么不同呢?我只是不明白为什么简单工厂对下面的示例根本不好.

无需在该链接上了解抽象工厂

推荐答案

T 他的代码&/thinsp;问题 不能说明抽象工厂或工厂方法.通过打开参数来确定要实例化哪个类的确是一种反模式,它鼓励违反开放式/封闭式原则.

THIS 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

通过一个预期有ToyFactory的USToyFactory会强制创建美国玩具(USToyBear和USToyElephant).这就是抽象工厂的力量.

Passing a USToyFactory where a ToyFactory is expected enforces the creation of US toys (USToyBear and USToyElephant) – this is the power of Abstract Factory.

请注意,产品(熊,大象等)是已知的AoT(提前出现).

Notice the products, bears, elephants, etc., are known AoT (ahead of time).

工厂方法

Factory方法只与将实例化延迟到子类有关.

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

调用createWidget()返回一个Widget,但是必须将要返回的具体Widget推迟到子类中(StatsDashboard返回StatsWidget).

Calling createWidget() returns a Widget, but which concrete Widget to return must be deferred to subclasses (StatsDashboard returns a StatsWidget).

请注意,创建方法在继承树上声明,但在继承树下实现.

❧敏锐的读者会发现Abstract Factory方法类似于Factory Methods,这是巧合吗?–不.这是派生Factory Method名称的地方(它们执行具体的类实例化).

❧ 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.

我希望这会有所帮助!

这篇关于与简单工厂相比,使用工厂方法模式有什么优势?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆