前言
研究了挺长时间设计模式,今天做一下记录。
首先,所有设计模式都会增加系统的复杂度。所以在系统不复杂的时候是绝对不能使用的,否则就是过度设计。换而言之如果你的项目不是太复杂的话,那么没有使用过设计模式才是正常的。
再者,所有设计模式基本都是六大设计原则的体现。设计原则是内功,而设计模式仅仅只是套路,换个语言甚至不同版本写法就天差地别。
工厂模式
主要有三种简单(静态)工厂、工厂方法、抽象工厂。
零售店买手机
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()
}
}
这样可能又有两个问题:
- 当新增一个 case 时,这个类会多非常多的代码,最后难以维护,所以要将其分离。
- 是所有的方法都叫 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()
}
}
总结
- 代码量不大的情况,就用简单工厂。
- 再复杂一些就用工厂方法。(但是如果你只有一条产线的话,那么直接使用类就可以了,还费啥劲搞个工厂)
- 如果有多个创建接口,就是抽象工厂。