JavaScript设计模式(二):工厂模式

工厂模式模式的定义与特点

  • 工厂模式(Factory Pattern)是编程中最常用的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。
  • 简单工厂模式:专门定义一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类。它又称为静态工厂方法模式。它的实质是由一个工厂类根据传入的参数,动态决定应该创建哪一个产品类(这些产品类继承自一个父类或接口)的实例。
  • 工厂方法模式:模式的表现只是一个抽象的方法。提前定义用于创建对象的接口,让子类(具体工厂)决定实例化具体的某一个类,即在工厂和产品中间增加接口(抽象工厂),工厂不再负责产品的创建,由接口针对不同条件返回具体的类实例,由具体类实例(具体工厂)去实现。
  • 抽象工厂模式:是所有形态的工厂模式中最为抽象和最具一般性的一种形态。抽象工厂模式是指当有多个抽象角色时,使用的一种工厂模式。抽象工厂模式可以向客户端提供一个接口,使客户端在不必指定产品的具体的情况下,创建多个产品族中的产品对象。

工厂模式的优点和缺点

  • 优点
  • 简单工厂模式:可以决定在什么时候创建哪一个产品类的实例,客户端可以免除直接创建产品对象的责任,而仅仅"消费"产品。外界与具体类隔离开来,偶合性低。明确区分了各自的职责和权力,有利于整个软件体系结构的优化。
  • 工厂方法模式:。简单工厂模式的工厂类随着产品类的增加需要增加很多方法(或代码),而工厂方法模式每个具体工厂类只完成单一任务,代码简洁。工厂方法模式完全满足OCP,即它有非常良好的扩展性。
  • 抽象工厂模式有助于这样的团队的分工,降低了模块间的耦合性,提高了团队开发效率。
  • 缺点
  • 简单工厂模式:当产品有复杂的多层等级结构时,工厂类只有自己,以不变应万变,就是模式的缺点。因为工厂类集中了所有产品创建逻辑,一旦增加产品或者删除产品,整个系统都要受到影响。系统扩展困难,一旦添加新产品就不得不修改工厂逻辑,有可能造成工厂逻辑过于复杂,违背了"开放--封闭"原则(OCP).另外,简单工厂模式通常使用静态工厂方法,这使得无法由子类继承,造成工厂角色无法形成基于继承的等级结构。
  • 工厂方法模式:假如某个具体产品类需要进行一定的修改,很可能需要修改对应的工厂类。当同时需要修改多个产品类的时候,对工厂类的修改会变得相当麻烦。比如说,每增加一个产品,相应的也要增加一个子工厂,会加大了额外的开发量。
  • 抽象工厂模式:抽象工厂模式在于难于应付“新对象”的需求变动。难以支持新种类的产品。难以扩展抽象工厂以生产新种类的产品。这是因为抽象工厂几乎确定了可以被创建的产品集合,支持新种类的产品就需要扩展该工厂接口,这将涉及抽象工厂类及其所有子类的改变。

抽象工厂模式例子

// 超级工厂类
  class Factory {
    constructor(choice) {
      choice = choice.toLocaleLowerCase();
      switch (choice) {
        case "person":
          return new Person();
        case "animal":
          return new Animal();
        default:
          break;
      }
    }
  }
  // 准备工厂类
  class AbstractFactory {
    // getPerson属于Person类的方法
    getPerson() {
      throw new Error("子类请实现接口");
    }
    // getAnimal属于Animaln类的方法
    getAnimal() {
      throw new Error("子类请实现接口");
    }
  }

  // Dog和Cat是属于Animate的产品
  class Dog {
    run() {
      console.log("狗");
    }
  }

  class Cat {
    run() {
      console.log("猫");
    }
  }
  // Male 和 Female 属于 Person 工厂的产品
  class Male {
    run() {
      console.log("男性");
    }
  }

  class Female {
    run() {
      console.log("女性");
    }
  }

  class Person extends AbstractFactory {
    getPerson(person) {
      person = person.toLocaleLowerCase();
      switch (person) {
        case "male":
          return new Male();
        case "female":
          return new Female();
        default:
          break;
      }
    }
    getAnimal() {
      return null;
    }
  }

  class Animal extends AbstractFactory {
    getPerson() {
      return null;
    }

    getAnimal(animal) {
      animal = animal.toLocaleLowerCase();
      switch (animal) {
        case "cat":
          return new Cat();
        case "dog":
          return new Dog();
        default:
          break;
      }
    }
  }

  // 实现Person类
  const person = new Factory("person");
  const male = person.getPerson("male"),
    female = person.getPerson("female");
  male.run();
  female.run();

  // 实现 Animate 类
  const animal = new Factory("animal");
  const dog = animal.getAnimal("dog"),
    cat = animal.getAnimal("cat");
  dog.run();
  cat.run();
posted @ 2021-04-12 14:04  亓亓哟  阅读(100)  评论(0编辑  收藏  举报