简单工厂模式(常用)

  1. 简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例;
  2. 简单工厂模式 优点
    • 只需要传入正确的参数,就可以获取需要的对象,无需知道创建细节;
    • 工厂类中有必要的 判断逻辑,可以决定根据当前的 参数 创建对应的 产品实例,客户端可以免除直接创建产品对象的责任;
    • 通过该模式,实现了对 创建实例使用实例 的责任分割 ;
    • 提供专门的工厂类用于 创建对象,客户端无需知道所创建的产品类的类名,只需要知道对应产品类的参数即可创建对象实例;
  3. 简单工厂模式 缺点
    • 工厂类职责过重,如果要增加新的产品,需要修改工厂类的判断逻辑,违背 “开闭原则”
    • 7 大设计原则,不能全部遵守,也不能不遵守,注意平衡功能和系统复杂度,找到最合适的一个点;
  4. 适用 场景
    • 创建对象少:工厂类 负责 创建的对象 比较少 ;
    • 不关心创建过程:客户端 只知道 传入 工厂类 的参数,对于 如何创建对象 不关心;

类图

bad

class Plant {
  constructor(name) {
    this.name = name;
  }
  grow() {
    console.log("growing~~~~~~");
  }
}

class Apple extends Plant {
  constructor(name) {
    super(name);
    this.taste = "甜";
  }
}

class Orange extends Plant {
  constructor(name) {
    super(name);
    this.taste = "酸";
  }
}

// 直接 new 的缺点
// - 1. 耦合(需要知道具体的类在哪里)
// - 2. 依赖具体的实现(大量业务用到了 Apple 类,若之后要修改 Apple 会造成很多的问题)
new Apple();
new Orange();

good

class Plant {
  constructor(name) {
    this.name = name;
  }
  grow() {
    console.log("growing~~~~~~");
  }
}

class Apple extends Plant {
  constructor(name) {
    super(name);
    this.taste = "甜";
  }
}

class Orange extends Plant {
  constructor(name) {
    super(name);
    this.taste = "酸";
  }
}

// 简单工厂
class Factory {
  static create(name) {
    switch (name) {
      case "apple":
        return new Apple("苹果");
      case "orange":
        return new Orange("橘子");
    }
  }
}

let apple = Factory.create("apple");
console.log(apple);
let orange = Factory.create("orange");
console.log(orange);

经典场景

  1. jQuery

    class jQuery {
      constructor(selector) {
        let elements = Array.from(document.querySelectorAll(selector));
        let length = elements ? elements.length : 0;
    
        for (let i = 0; i < length; i++) {
          this[i] = elements[i];
        }
        this.length = length;
      }
    
      html() { }
    
      // ...
    }
    
    window.$ = function (selector) {
      return new jQuery(selector);
    }
    
  2. React

    class Vnode {
      constructor(tag, attrs, children) {
        this.tag = tag;
        this.attrs = attrs;
        this.children = children;
      }
    }
    
    React.createElement = function (tag, attrs, children) {
      return new Vnode(tag, attr, children);
    }
    

工厂方法模式

  1. 工厂方法模式 Factory Method,又称多态性工厂模式,在工厂方法模式中,核心的工厂类不再负责所有的产品的创建,而是将具体创建的工作交给子类去做;

  2. 工厂方法模式 优点

    • 不关心创建细节:用户只需要关心 所需产品对应的工厂,无需关心 创建细节
    • 符合开闭原则:加入新产品,符合 开闭原则,提高 可扩展性
  3. 工厂方法模式 缺点

    • 增加复杂性:类的个数容易过多,增加 系统复杂度
    • 添加新产品时,除了编写 新的产品类 之外,还要 编写该产品类对应的工厂类
    • 增加难度:增加了系统 抽象性理解难度
  4. 工厂方法模式适用 场景

    • 重复代码:创建对象 需要使用 大量重复的代码;
    • 不关心创建过程:客户端 不依赖 产品类,不关心 实例 如何被创建,实现等细节;
    • 创建对象:一个类 通过其 子类指定 创建哪个对象;

类图

实现代码

class Plant {
  constructor(name) {
    this.name = name;
  }
  grow() {
    console.log('growing~~~~~~');
  }
}

class Apple extends Plant {
  constructor(name) {
    super(name);
    this.taste = '甜';
  }
}

class Orange extends Plant {
  constructor(name) {
    super(name);
    this.taste = '酸';
  }
}

class AppleFactory {
  create() {
    return new Apple();
  }
}

class OrangeFactory {
  create() {
    return new Orange();
  }
}

// 工厂方法模式中,使用工厂类创建产品对象,同时隐藏了具体的产品类被实例化的细节
const settings = {
  'apple': AppleFactory,
  'orange': OrangeFactory
}

let apple = new settings['apple']().create();
console.log(apple);
let orange = new settings['orange']().create();
console.log(orange);

抽象工厂模式

  1. 抽象工厂模式是指当有多个抽象角色时,使用的一种工厂模式,抽象工厂模式可以向客户端提供一个接口,使客户端在不必指定产品的具体的情况下,创建多个产品族中的产品对象;

  2. 抽象工厂模式 优点

    • 隔离产品代码:在 应用层 隔离 具体产品的代码,客户端 无须关心 产品创建 的细节;
    • 创建产品族:将 一个系列产品族,统一到 一起创建
  3. 抽象工厂模式 缺点

    • 扩展困难:规定了 所有 可能被创建产品集合,产品族中 扩展 新的产品 困难,需要 修改抽象工厂的接口
    • 增加难度:增加了系统的 抽象性理解难度
  4. 抽象工厂模式适用 场景

    • 忽略创建细节:客户端 不关心 产品实例 如何 被创建 实现等细节;
    • 创建产品族:强调 一系列 相关的 产品对象,一般是 同一个产品族,一起使用 创建对象 需要大量 重复的代码
    • 产品类库:提供 一个 产品类 的库,所有的产品 以 同样的接口出现,使 客户端不依赖于具体实现;

类图

实现代码

class Button {
  render() {

  }
}
class AppleButton {
  render() {
    console.log('苹果按钮');
  }
}
class WindowButton {
  render() {
    console.log('Windows按钮');
  }
}

class Icon {
  render() {

  }
}
class AppleIcon {
  render() {
    console.log('苹果图标');
  }
}
class WindowIcon {
  render() {
    console.log('Windows图标');
  }
}

class Factory {
  createButton() { }
  createIcon() { }
}
class AppleFactory extends Factory {
  createButton() {
    return new AppleButton();
  }
  createIcon() {
    return new AppleButton();
  }
}
class WindowsFactory extends Factory {
  createButton() {
    return new WindowButton();
  }
  createIcon() {
    return new WindowIcon();
  }
}

const settings = {
  'apple': AppleFactory,
  'windows': WindowsFactory
}
let appleFactory = new settings['apple']();
appleFactory.createButton().render();
appleFactory.createIcon().render();

let windowsFactory = new settings['windows']();
windowsFactory.createButton().render();
windowsFactory.createIcon().render();

对比

  1. 简单工厂:一般就是一个函数返回产品的实例;

  2. 工厂方法:多了工厂类,想要创建产品,需要先创建此工厂的实例,再通过此工厂来创建实例;

  3. 抽象工厂:一个工厂可以创建多种产品;

打赏作者
您的打赏是我前进的动力
微信
支付宝
评论

中午好👏🏻,我是 ✍🏻   疯狂 codding 中...

粽子

这有关于前端开发的技术文档和你分享。

相信你可以在这里找到对你有用的知识和教程。

了解更多

目录

  1. 1. 简单工厂模式(常用)
    1. 1.1. 类图
    2. 1.2. bad
    3. 1.3. good
    4. 1.4. 经典场景
  2. 2. 工厂方法模式
    1. 2.1. 类图
    2. 2.2. 实现代码
  3. 3. 抽象工厂模式
    1. 3.1. 类图
    2. 3.2. 实现代码
  4. 4. 对比