持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第14天,点击查看活动详情
前言
在面向对象的开发过程中,其实咱们或多或少的都接触过一些设计模式,可能知道或不知道其对应的名称,也不知道其具体使用场景,今天咱们就来说说几种常见的设计模式,帮助你们在开发过程中,更加得心应手。
正文
工厂模式
工厂模式根据抽象程度的不同分为三种:简单工厂模式(也叫静态工厂模式)、工厂方法模式、抽象工厂模式。
简单工厂模式
根据传入的参数的不同,返回不同的类的实例。
简单工厂模式专门定义一个类来负责创建其他类的实例,被创建的实例通常都具有共同的父类。
例子:Button的样式,可根据传入不同的枚举,输出相应样式的按钮。
enum Style {case mac, win}
protocol Button {}
class MacButton: Button {}
class WinButton: Button {}
class ButtonFactory {
func createButton(style: Style) -> Button {
switch style {
case .mac:
return MacButton()
default:
return WinButton()
}
}
}
var style: Style = .mac
var fac = ButtonFactory()
fac.createButton(style: style)
复制代码
工厂方法模式
工厂方法模式是简单工厂的进一步深化
在这个模式中,会对不同的对象提供不同的工厂方法。也就是说每个对象都有一个与之对应的工厂。
定义一个创建对象的接口,但让实现这个接口的类来决定实例化哪个类。工厂方法让类的实例化推迟到子类中进行
例子1:Reader 的样式。
有一个Reader类表示图片读取,另有它的三个子类 JPGReader, PNGReader和 GIFReader 分别代表 jpg、png 和 gif 读取。
protocol Reader {
func read()
}
class JPGReader : Reader {
func read() {
print("read jpg")
}
}
class PNGReader: Reader {
func read() {
print("read png")
}
}
class GIFReader: Reader {
func read() {
print("read gif")
}
}
protocol ReaderFactory {
func getReader() -> Reader
}
class JPGReaderFactory : ReaderFactory {
func getReader() -> Reader {
JPGReader()
}
}
class PNGReaderFactory: ReaderFactory {
func getReader() -> Reader {
PNGReader()
}
}
class GIFReaderFactory: ReaderFactory {
func getReader() -> Reader {
GIFReader()
}
}
// 读取GIF
var factory: ReaderFactory = GIFReaderFactory()
var reader: Reader = factory.getReader()
reader.read()
// 读取png
factory = PNGReaderFactory()
reader = factory.getReader()
reader.read()
// 读取 JPG
factory = JPGReaderFactory()
reader = factory.getReader()
reader.read()
复制代码
抽象工厂模式
为创建一组相关或相互依赖的对象提供一个接口,而且无需指定他们的具体类。
例子: 汽车样例
假设我们有两种产品接口 BenzCar、AudiCar 和 BmwCar ,每一种产品都支持多种系列,比如 Sport 系列和 Business 系列。这样每个系列的产品分别是 BenzSportCar, BenzBusinessCar, BmwSportCar, BmwBusinessCar,AudiSportCar,AudiBusinessCar 。为了可以在运行时刻创建一个系列的产品族,我们可以为每个系列的产品族创建一个工厂 SupportDriver 和 BusinessDriver 。每个工厂都有三个方法 createBenzCar ,createBmwCar 和 createAudiCar 并返回对应的产品,可以将这三个方法抽象成一个接口 Driver 。这样在运行时刻我们可以选择创建需要的产品系列。
class BenzCar {
var name: String
init(name: String) {
self.name = name
}
func drive() {}
}
class BenzSportCar : BenzCar {
override func drive() {
print("(name) :: BenzSportCart")
}
}
class BenzBusinessCar : BenzCar {
override func drive() {
print("(name) :: BenzBusinessCar")
}
}
class BmwCar {
var name: String
init(name: String) {
self.name = name
}
func drive() {}
}
class BmwSportCar : BmwCar {
override func drive() {
print("(name) :: BmwCSportCart")
}
}
class BmwBusinessCar : BmwCar {
override func drive() {
print("(name) :: BmwBusinessCar")
}
}
class AudiCar {
var name: String
init(name: String) {
self.name = name
}
func drive() {}
}
class AudiSportCar : AudiCar {
override func drive() {
print("(name) :: AudiCSportCart")
}
}
class AudiBusinessCar : AudiCar {
override func drive() {
print("(name) :: AudiBusinessCar")
}
}
protocol Driver {
func createBenzCar(car: String) -> BenzCar
func createBmwCar(car: String) -> BmwCar
func createAudiCar(car: String) -> AudiCar
}
class SupportDriver : Driver {
func createBenzCar(car: String) -> BenzCar {
BenzSportCar.init(name: car)
}
func createBmwCar(car: String) -> BmwCar {
BmwSportCar.init(name: car)
}
func createAudiCar(car: String) -> AudiCar {
AudiSportCar.init(name: car)
}
}
class BusinessDriver: Driver {
func createBenzCar(car: String) -> BenzCar {
BenzBusinessCar.init(name: car)
}
func createBmwCar(car: String) -> BmwCar {
BmwBusinessCar.init(name: car)
}
func createAudiCar(car: String) -> AudiCar {
AudiBusinessCar.init(name: car)
}
}
let driver = BusinessDriver()
let car = driver.createAudiCar(car: "BusinessDriver")
car.drive()
复制代码
三者的对比
结语
在日常开发中,简单工厂模式应该是用的最多的,但是缺点也是十分明显。其他两种模式,也有不同程度的优缺点,大家需要根据实际情况进行选择。 ,