「这是我参与11月更文挑战的第12天,活动详情查看:2021最后一次更文挑战」
摘要
工厂方法模式是整合代码,减少 if-else 代码的一直很好的方式,不过相对应的也会增加创建子类。若 if-else 使用的比较多,可以考虑重构成工厂方法模式。
工厂方法模式属于创建型模式,就是在创建实例的时候被使用。它使用 protocol
(协议)方法来实现。凡是遵守这个协议的子类或者子结构体都可以调用统一的接口实现。
遵守工厂方法模式协议的子类可以用重写的方式自定义函数的实现方式。也就是对外调用同一个函数,返回对象,内部有不同的处理。
具体场景有根据系统语言显示对应语言的文本,还有就是一个标识在多个函数做 if-elese 处理的地方,都是可以考虑重构成工厂方法模式。
同时它也可以用作扩展库或者内部组件,说到扩展,有可能想到的是继承,继承确实也可以做到扩展,但是有一个现实的问题,当用继承来扩展子类,对使用来说,它怎么知道这个子类呢?工厂方法就可以将所用子类集合到自身的工厂方法里面,避免这个问题。
接下来,来过一下工厂方法的设计流程:
首先要创建一个协议,声明一个创建对象方法,和其他一些操作方法。这里有一个创建对象的方法返回实例,是出于下面声明的函数是实例函数,而不是类函数。
protocol Creator {
func newCreator() -> Product
func otherOperations()
}
复制代码
如果协议中声明的函数不是必须要遵守者实现的,或者已经有默认实现,就可以在 extension
中实现。如果子类需要自定义的处理,就完全可以重写这个方法就可以。
extension Creator {
func otherOperations() {
print("这是默认实现")
}
}
复制代码
在 newCreator()
函数中返回的 Product
也是一个协议,来处理返回的实例。
protocol Product {
func somePoertations()
}
复制代码
到这里,完成了工厂方法的规定,之后就是创建子类遵守协议。
class ACreator: Creator {
func newCreator() -> Product {
return APruduct()
}
}
复制代码
为了做对比,再创建一个类,也遵守协议:
class BCreator: Creator {
func newCreator() -> Product {
return BPruduct()
}
}
复制代码
到这里,会发现 newCreator
返回的是 Product
,但是为什么是 APruduct
和 BPruduct
类型呢?
因为接下来要创建两个不同的类来遵守 Product
协议:
class AProduct: Product {
func somePoertations() {
print("APruduct")
}
}
复制代码
继续创建另外一个:
class BProduct: Product {
func somePoertations() {
print("BPruduct")
}
}
复制代码
到这里,就可以看到 ACreator
或者 BCreator
都可以用 Creator
来定义。Product
也可以代替 APrudct
和 BPrudct
被定义。这就是将自定义的方法给统一归属到一个地方。外部调用只认这个对外的定义就可以了。
最后就是使用它,这里就可以创建一个 Client
类,实现一下
class Client {
funct clientOperation(creator: Creator) {
// Creator 中的方法
creator.otherOperations()
// Product 中的方法
creator.newCreator.somePoertations()
}
}
复制代码
到这里完成了工厂方法模式的实现逻辑,可以发现 protocol
的整个承接作用,以及它还可以作为返回值类型,厉害。
题外话
设计模式比较抽象,需要多温习,多实践,才能很好吸收。所以本文会时时更新,力求把抽象说的更具体。没有考虑到的地方,可以评论区和我留言讨论。