工厂模式

什么是工厂模式?

工厂模式是一种创建型设计模式,其在父类中提供一个创建对象的方法,允许子类决定实例化对象的类型。

如何使用

工厂模式建议使用特殊的工厂方法代替对于对象构造函数的直接调用(即使用 new 运算符)。不用担心,对象仍将通过 new 运算符创建,只是该运算符改在工厂方法中调用罢了。

interface Product {
  operation(): string;
}

class ConcreteProduct1 implements Product {
  public operation(): string {
    return '型号1--爆炸果实'
  }
}

class ConcreteProduct2 implements Product {
  public operation(): string {
    return '型号2--治疗果实'
  }
}
/**
 * 工厂模式
 */
abstract class Creator {
  public abstract factoryMethod(): Product;

  /**
        * 注意,尽管其名称,创作者的主要责任是
        * 不创造产品。 通常,它包含一些核心业务逻辑
        * 依赖于工厂方法返回的 Product 对象。 子类可以
        * 通过覆盖工厂方法间接改变业务逻辑
        * 并从中返回不同类型的产品。
        */
  public someOperation(): string {
    const product = this.factoryMethod();
    return `产品详情:${product.operation()}`
  }
}

class ConcreteCreator1 extends Creator {
  /**
   * factoryMethod: Product
   */
  public factoryMethod(): Product {
    return new ConcreteProduct1();
  }
}
class ConcreteCreator2 extends Creator {
  /**
   * factoryMethod: Product
   */
  public factoryMethod(): Product {
    return new ConcreteProduct2();
  }
}

/**
      * 注意方法的签名还是使用抽象积
      * 类型,即使具体产品实际上是从
      * 方法。 通过这种方式,创造者可以保持独立于具体产品
      * 类
      */
function productPlan(creator: Creator) {
  console.log('计划生产');
  console.log(creator.someOperation());
}

console.log('App: Launched with the ConcreteCreator1.');
productPlan(new ConcreteCreator1());
console.log('');

console.log('App: Launched with the ConcreteCreator2.');
productPlan(new ConcreteCreator2());

输出:

App: Launched with the ConcreteCreator1.
计划生产
产品详情:型号1--爆炸果实

App: Launched with the ConcreteCreator2.
计划生产
产品详情:型号2--治疗果实

实现方式

  1. 接口统一。
  2. 在创建类中添加一个返回通用类型的工厂方法。
  3. 将产品构造函数的引用依次替换为工厂方法的调用,同时将创建产品的代码移入工厂方法。
  4. 为工程方法中的产品创建子类,在子类中重写工厂方法,并且将基本方法中的相关代码移动到工厂的方法中。

适用场景

  • 当你在编写代码的过程中,如果无法预知对象确切类别及其依赖关系时,可使用工厂方法。
  • 如果希望用户能扩展软件库或者框架的内部组件。
  • 复用现有对象节省系统资源,不希望每次创建对象。、

优缺点

  • 避免创建者和产品的耦合
  • 单一职责原则,代码更易维护
  • 开闭原则,代码迭代方便
  • 引入新的子类导致代码结构复杂

参考