【问题标题】:Interfaces and classes vs Simple Factory design pattern接口和类与简单工厂设计模式
【发布时间】:2017-10-30 13:53:34
【问题描述】:

我的一个朋友告诉我,如果我想成为一名优秀的程序员,那么我需要学习设计模式。我从那个网站开始: https://github.com/kamranahmedse/design-patterns-for-humans

我从简单工厂开始。 正如您在该页面上看到的,您需要实施:

  • 界面门
  • 木门类
  • 类DoorFactory

你可以像这样使用它(PHP):

$door = DoorFactory::makeDoor(100, 200);
echo 'Width: ' . $door->getWidth();
echo 'Height: ' . $door->getHeight();

但我想知道为什么我需要类 DoorFactory 的层,当我可以简单地这样做时,它会为我提供具有给定参数的 WoodDoor 的新实例:

Door door = new WoodenDoor(100, 200);

当我可以通过使用 new ClassName 语句传递给定的构造函数参数来简单地创建实例时,创建该工厂有什么大不了的?


已编辑

说明我可以通过此解决方案轻松管理多次出现的给定元素废除的变化:

创建给定的类(作为工厂解决方案中的给定工厂类型),例如:

类 LongWoodenDoor 扩展了 WoodDoor 类并使用带有给定参数的 WoodDoor 构造函数。例如通过使用 super("100", "200");

【问题讨论】:

标签: php design-patterns factory-pattern


【解决方案1】:

你绝对可以使用

Door door = new WoodenDoor(100, 200);

创建门,但我会引用您正在遵循的教程:

简单工厂只是为客户端生成一个实例,而不向客户端公开任何实例化逻辑

工厂的目的是客户端不需要知道门类的构造函数就可以创建门。

你的工厂在创建门时可以不带任何参数:

makeDoor 函数:

Door* DoorFactory::makeDoor()
{
    Door *newDoor = new Door(200, 100);
    return newDoor;
}

您创建门的位置:

Door door = DoorFactory::makeDoor();

在这种情况下,工厂正在封装有关门的信息,因此您无需了解门的尺寸。显然,您希望能够灵活地使用自己的尺寸定义门,但在某些情况下,隐藏参数以避免更改是有益的。

另外,如果你以后想修改类 Door 的构造函数,比如添加另一个名为 thickness 的参数:

Door::Door(double width, double height, double thickness)

您不必更改项目中的每一个门实例,您只需在一个地方修改您的工厂代码:

Door* DoorFactory::makeDoor(double width, double height)
{
    Door *newDoor = new Door(width, height, 5);
    return newDoor;
}

这样,如果您的项目需求发生变化,重构会更容易。

【讨论】:

  • 好吧。但我可以创建类,例如 LongWoodenDoor,它将实现 WoodDoor。而在 LongWoodenDoor 构造函数中,它将简单地调用具有常量参数的 super(WoodenDoor 构造函数)。我会称它为 Door door = new LongWoodeDoor();而且我这里也没有关于尺寸的信息。
  • 您可能会这样做:DoorFactory::makeDoor("normal wood door");DoorFactory::makeDoor("long wood door"); 然后在工厂中修改您的逻辑。抱歉,我没有太多使用 Factory 的经验。
【解决方案2】:

设计模式真是个好建议!
factory method 模式也是很好的建议。工厂方法的目的是定义一个用于创建对象的接口,但是您可以在 runtime 中确定要创建的对象!因此,如果您不知道是木门还是金属门或塑料门 - 您必须使用工厂方法。

但如果你确定它会是木头 - 你可以坚持使用 KISS(保持简单,愚蠢)和 YAGNI(你不需要它)原则。

【讨论】:

  • 但我也可以在运行时确定它,当我将执行 LongWoodenDoor 类时,它将通过简单地运行带有给定参数的 WoodDoor 的构造函数来扩展 WoodDoor,然后我也可以在运行时管理它。我将使用哪个扩展类。
  • 是的,你可以做到 - 这是选项 #1,但选项 #2 - 工厂。你会选择什么 - 你会决定。这只是另一种选择......
  • 所以最后我不需要实现简单工厂。只是我需要知道如何解决问题?
  • 一般来说 - 是的!发展——是创造性的工作……你可以用不同的方式解决问题……更重要的是——达到目标。你是怎么做到的 - 这是另一个对话......
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-11
  • 1970-01-01
  • 1970-01-01
  • 2015-12-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多