luoxue-victor / my-blog

公众号【前端技匠】作者

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

专题4: 设计模式之工厂模式

luoxue-victor opened this issue · comments

工厂模式

目的

定义一个创建对象的接口,让其子类自己决定实例化哪一个工厂类,工厂模式使其创建过程延迟到子类进行

使用场景

我们明确地计划不同条件下创建不同实例时

优缺点

优点

  1. 隐藏了对象创建的细节,将产品的实例化过程放到了工厂中实现。
  2. 客户端基本不用关心使用的是哪个产品,只需要知道用工厂的那个方法(或传入什么参数)就行了.
  3. 方便添加新的产品子类,每次只需要修改工厂类传递的类型值就行了。
  4. 遵循了依赖倒转原则。

缺点

  1. 适用于产品子类型差不多, 使用的方法名都相同的情况.
  2. 每添加一个产品子类,都必须在工厂类中添加一个判断分支(或一个方法),这违背了OCP(开闭原则)。

实现

比如我要有一个 Animal 工厂,这个工厂要生产动物。那么我要定义动物都有 Feature特征必须要有 color 颜色跟 bark 叫声。

1. 接口实现

// 定义工厂需要的动物特征
interface Feature {
  color: string;
  bark(): void;
}

// 定义动物类型名字
type name = 'cat' | 'dog'

// 子类必须要实现 Feature 接口的方法
// 这样我们就可以创建白色叫声喵喵喵的猫了
class Cat implements Feature {
  color = "白色";
  bark() {
    console.log(`${this.color} 喵喵喵`);
  }
}
// 创建 Dog 类
class Dog implements Feature {
  color = "黑色";
  bark() {
    console.log(`${this.color} 汪汪汪`);
  }
}
// 这就是一个动物工厂
class Animal {
  createAnimal(type: name) {
    switch (type) {
      case 'cat':
        return new Cat();
      case 'dog':
        return new Dog();
    }
  }
}

const animal = new Animal();
const cat = animal.createAnimal('cat');
const dog = animal.createAnimal('dog');

cat.bark()
dog.bark()

2. 抽象类实现

abstract class Feature {
  abstract color: string;
  abstract bark(): void;
}

// 枚举可以使用的动物类型
enum animalType {
  'cat',
  'dog'
}

// 子类继承抽象类 Feature
// 这样我们就可以创建白色叫声喵喵喵的猫了
class Cat extends Feature {
  color = "白色";
  bark() {
    console.log(`${this.color} 喵喵喵`);
  }
}
// 创建 Dog 类
class Dog extends Feature {
  color = "黑色";
  bark() {
    console.log(`${this.color} 汪汪汪`);
  }
}
// 这就是一个动物工厂
class Animal {
  createAnimal(type: animalType) {
    switch (type) {
      case animalType.dog:
        return new Cat();
      case animalType.dog:
        return new Dog();
    }
  }
}

const animal = new Animal();
const cat = animal.createAnimal(animalType.cat);
const dog = animal.createAnimal(animalType.dog);

cat.bark()
dog.bark()

对new的封装