JavaScript 面向对象模式工厂模式

组织代码将为我们节省大量的痛苦。使用对象导向编程的功能(https://andsky.com/tech/tutorials/js-objects-prototypes-classes),我们可以使用某些设计模式来实现更好的可读性,减少冗余,并在必要时创建抽象。

工厂模式是一种类型的面向对象模式,它遵循DRY方法,正如其名称所示,对象实例是通过使用工厂来为我们制作所需的对象来创建的。

让我们来看看一个非常简单的例子,使用工厂模式来组装一个合金器对象. 为了做到这一点,我们首先需要制造制造合金器部件的工厂:

 1class TailFactory {
 2  constructor(props) {
 3    this.tailLength = props.tailLength;
 4  }
 5};
 6
 7class TorsoFactory {
 8  constructor(props) {
 9    this.color = props.color;
10  }
11};
12
13class HeadFactory {
14  constructor(props) {
15    this.snoutLenth = props.snoutLenth;
16  }
17};

现在,我们创建了一个类,作为实际工厂类和用户之间的中间人,让我们称之为ReptilePartFactory:

 1class ReptilePartFactory {
 2  constructor(type, props) {
 3    if(type === "tail")
 4      return new TailFactory(props);
 5    if(type === "torso")
 6      return new TorsoFactory(props);
 7    if(type === "head")
 8      return new HeadFactory(props);
 9  }
10};

让我们现在继续进行并组装实际的鱼,并使用ReptilePartFactory为我们提供所需的零部件:

 1let alligator = {};
 2let alligatorProps = {
 3  tailLength : 2.5, 
 4  color: "green",
 5  snoutLenth: 1
 6};
 7
 8//gets a tail from the tail factory
 9alligator.tail  = new ReptilePartFactory("tail", alligatorProps); 
10
11//gets a torso from the torso factory
12alligator.torso = new ReptilePartFactory("torso", alligatorProps);
13
14//gets a head from the head factory
15alligator.head  = new ReptilePartFactory("head", alligatorProps);

看看上面的图案,似乎我们可以使用相同的ReptilePartFactory来创建对象的零部件。

因此,使用工厂模式给了我们一定的优势:

  • 动态对象创建:可以在运行时决定对象类型的情况下使用
  • 抽象:用户从不真正需要访问实际对象的构造器
  • 可重复使用/维护:相同的工厂可以用于类似的对象,它允许我们轻松地添加/删除新的对象类,而无需更改大量的代码

现在我们对工厂模式有了一些了解,让我们来探索写出更好的工厂模式代码。

上面的例子使用一个如果梯子来找出基于用户输入来调用哪个工厂。这是一个简单的实现,直观的,不太开放的变化。如果我们有新的部件要添加以后,那么我们将不得不干扰ReptilePartFactory。这是违反SOLID原则,其中说软件实体(类,模块,函数等)应该开放扩展,但关闭修改

我们如何在一个对象中存储工厂类,并通过使用我们想要的部分作为钥匙来调用所需的零部件工厂?首先我们需要注册工厂,这将是简单的:

 1let registeredPartFactories = {};
 2registeredPartFactories['tail'] = class TailFactory{
 3  ...
 4};
 5
 6registeredPartFactories['torso'] = class TorsoFactory {
 7  ...
 8};
 9
10registeredPartFactories['head'] = class HeadFactory {
11  ...
12};

现在,抽象层可以这样称呼工厂:

1class ReptilePartFactory {
2  constructor(type, props) {
3    return new registeredPartFactories[type](props);
4  }
5};

这种方法更清洁,可以扩大我们的工厂,而不会影响ReptilePartFactory中的代码。

结论

还有几种其他面向对象的模式也增加了可读性和质量,所以在使用工厂模式之前,请检查是否有真正的要求。如果您要重复创建类似类型的对象,并且还需要一个层来使用这些对象创建新实例,同时为创建逻辑提供一些抽象水平,那么是的 - 工厂模式是一个很好的选择。

Published At
Categories with 技术
Tagged with
comments powered by Disqus