聊聊Swift中的设计模式---创建型(工厂模式)

持续创作,加速成长!这是我参与「掘金日新计划 · 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()
复制代码

三者的对比

截屏2022-06-07 上午10.46.26.png

结语

在日常开发中,简单工厂模式应该是用的最多的,但是缺点也是十分明显。其他两种模式,也有不同程度的优缺点,大家需要根据实际情况进行选择。 ,

猜你喜欢

转载自juejin.im/post/7106325463630839821
今日推荐