JavaScript面向对象模式:工厂模式
组织代码将使我们免于很多痛苦。 使用面向对象编程的特性,我们可以使用某些设计模式来获得更好的可读性,减少冗余并在需要时创建抽象。 一种这样的模式是工厂模式。
工厂模式是一种遵循 DRY 方法的面向对象模式。 顾名思义,对象实例是通过使用工厂为我们制作所需的对象来创建的。
让我们看一个使用工厂模式组装 alligator
对象的非常简单的示例。 为此,我们首先需要创建为我们创建 alligator
零件的工厂:
class TailFactory { constructor(props) { this.tailLength = props.tailLength; } }; class TorsoFactory { constructor(props) { this.color = props.color; } }; class HeadFactory { constructor(props) { this.snoutLenth = props.snoutLenth; } };
现在,我们创建一个类作为实际工厂类和用户之间的中介。 我们称之为 ReptilePartFactory
:
class ReptilePartFactory { constructor(type, props) { if(type === "tail") return new TailFactory(props); if(type === "torso") return new TorsoFactory(props); if(type === "head") return new HeadFactory(props); } };
现在让我们继续组装真正的鳄鱼,并使用 ReptilePartFactory
为我们获取所需的零件:
let alligator = {}; let alligatorProps = { tailLength : 2.5, color: "green", snoutLenth: 1 }; //gets a tail from the tail factory alligator.tail = new ReptilePartFactory("tail", alligatorProps); //gets a torso from the torso factory alligator.torso = new ReptilePartFactory("torso", alligatorProps); //gets a head from the head factory alligator.head = new ReptilePartFactory("head", alligatorProps);
看看上面的模式,似乎我们可以使用相同的 ReptilePartFactory
来为类似鳄鱼的对象创建部件。 背景中的工厂永远不必知道最终对象的性质。
因此,使用工厂模式给了我们一些优势:
- 动态对象创建:可用于在运行时确定对象类型的情况。
- Abstraction:用户永远不必访问实际对象的构造函数。
- 可重用性/维护:相同的工厂可以用于类似的对象,它允许我们轻松添加/删除新的对象类,而无需更改大量代码。
现在我们对工厂模式有了一些了解,让我们来探索一下如何编写更好的工厂模式代码。
上面的示例使用 if-ladder 根据用户输入找出要调用的工厂。 这是一个简单的实现,直观且对更改不太开放。 如果我们以后有新的零件要添加,那么我们就不得不打扰ReptilePartFactory
。 这违反了 SOLID 原则,即“软件实体(类、模块、函数等)应该对扩展开放,但对修改关闭”。
我们如何将工厂类存储在一个对象中,并使用我们想要的部分作为键调用所需的部分工厂? 首先我们必须注册工厂,它很简单:
let registeredPartFactories = {}; registeredPartFactories['tail'] = class TailFactory{ ... }; registeredPartFactories['torso'] = class TorsoFactory { ... }; registeredPartFactories['head'] = class HeadFactory { ... };
现在,抽象层可以像这样调用工厂:
class ReptilePartFactory { constructor(type, props) { return new registeredPartFactories[type](props); } };
这种方法更简洁,允许扩展我们的工厂而不影响 ReptilePartFactory
中的代码。
综上所述
还有其他几种面向对象的模式也提高了可读性和质量。 因此,在使用工厂模式之前,请检查是否有真正的需求。 如果您要重复创建类似类型的对象,并且还需要一个层来使用这些对象创建新实例,同时为创建逻辑提供一定程度的抽象,那么可以——工厂模式是一个不错的选择。