TS 设计模式-工厂模式

27 阅读2分钟

前言

研究了挺长时间设计模式,今天做一下记录。

首先,所有设计模式都会增加系统的复杂度。所以在系统不复杂的时候是绝对不能使用的,否则就是过度设计。换而言之如果你的项目不是太复杂的话,那么没有使用过设计模式才是正常的。

再者,所有设计模式基本都是六大设计原则的体现。设计原则是内功,而设计模式仅仅只是套路,换个语言甚至不同版本写法就天差地别。

工厂模式

主要有三种简单(静态)工厂、工厂方法、抽象工厂。

零售店买手机

interface Phone {
  playGame: () => void
}

interface Factory {
  create(type: string): Phone
}

class IPhone implements Phone {
  playGame() {
    console.log("使用 iphone 玩游戏")
  }
}

class XiaomiPhone implements Phone {
  playGame() {
    console.log("使用 xiaomi 玩游戏")
  }
}

type PhoneBrand = "apple" | "xiaomi"
class Factory {
  static create(type: PhoneBrand): Phone {
    switch (type) {
      case "apple":
        return new IPhone()
      case "xiaomi":
        return new XiaomiPhone()
    }
  }
}

上面这个就是简单工厂的实现方式。唯一的问题就是静态方法。下面会改写成构造器模式。

相当于零售店,你想拿到什么品牌的手机都可以。如果新的手机品牌那么增加一个 case 即可。

这里其实隐藏了一个问题,就是当创建手机这个步骤非常复杂时,要将其封装成一个方法。

class FactoryMethod {
  #type: PhoneBrand
  constructor(type: PhoneBrand) {
    this.#type = type
  }
  create(): Phone {
    switch (this.#type) {
      case "apple":
        return this.createApple()
      case "xiaomi":
        return this.createXiaoPhone()
    }
  }

  createApple() {
    // 上面还有很代码
    return new IPhone()
  }

  createXiaoPhone() {
    // 上面还有很代码
    return new XiaomiPhone()
  }
}

这样可能又有两个问题:

  1. 当新增一个 case 时,这个类会多非常多的代码,最后难以维护,所以要将其分离。
  2. 是所有的方法都叫 createXXX,在意图上重复。

工厂生产手机

工厂方法,就是为所有的品牌建一个工厂。这样可以用这个工厂,批量生产手机,但是问题就是多了一个类。

// 使用工厂方法
interface PhoneFactory {
  create: () => Phone
}

class IPhoneFactory implements PhoneFactory {
  create() {
    // 上面还有很代码
    return new IPhone()
  }
}

class XiaomiFactory implements PhoneFactory {
  create() {
    // 上面还有很代码
    return new XiaomiPhone()
  }
}

工厂生产耳机

如果我还需要耳机,要怎么扩展呢?抽象工厂增加不同的产线,这样就可以用不同的产线去生产产品。

// 新增耳机
interface Pods {
  playMusic: () => void
}

class IPods implements Pods {
  playMusic() {
    console.log("使用 iphone 听音乐")
  }
}

class XiaomiPods implements Pods {
  playMusic() {
    console.log("使用 xiaomi 听音乐")
  }
}

interface BrandFactory {
  createPhone: () => Phone
  createPods: () => Pods
}

class IPhoneFactory1 implements BrandFactory {
  createPhone() {
    // 上面还有很代码
    return new IPhone()
  }
  createPods() {
    return new IPods()
  }
}

class XiaomiFactory1 implements BrandFactory {
  createPhone() {
    // 上面还有很代码
    return new XiaomiPhone()
  }
  createPods() {
    return new XiaomiPods()
  }
}

总结

  1. 代码量不大的情况,就用简单工厂。
  2. 再复杂一些就用工厂方法。(但是如果你只有一条产线的话,那么直接使用类就可以了,还费啥劲搞个工厂)
  3. 如果有多个创建接口,就是抽象工厂。