設(shè)計(jì)模式-創(chuàng)建型

設(shè)計(jì)模式-創(chuàng)建型

創(chuàng)建型設(shè)計(jì)模式包含:單例模式、原型模式撇叁、工廠方法模式供鸠、抽象工廠模式、建造者模式

單例模式

單例模式在開發(fā)中也是最常見的一種設(shè)計(jì)模式之一陨闹,系統(tǒng)原生提供的很多類的設(shè)計(jì)都采用了單例模式楞捂,例如:

FileManager.default
UserDefaults.standard
NotificationCenter.default
UIApplication.shared
URLSession.shared

其目的是為了節(jié)省內(nèi)存資源并保證數(shù)據(jù)內(nèi)容的一致性,需要讓某些類只能創(chuàng)建一個(gè)實(shí)例趋厉。單例模式有如下特點(diǎn):

  • 單例類只有一個(gè)實(shí)例對(duì)象
  • 單例類的實(shí)例對(duì)象由自己創(chuàng)建
  • 需要對(duì)外提供一個(gè)訪問其實(shí)例對(duì)象的接口

在軟件設(shè)計(jì)中寨闹,有關(guān)全局共享的資源數(shù)據(jù),大型通用的管理類等都可以使用單例模式君账,例如登錄用戶的用戶信息類繁堡、全局的計(jì)時(shí)器、程序的日志管理類

Swift 單例

class ClassA {
    static let share = ClassA()
}

Objective-C 單例

static XXClassManager *_defaultManager;
+ (instancetype)shareInstance {
    if (!_defaultManager) {
        _defaultManager = [[self alloc] init];
    }
    return _defaultManager;
}
+ (instancetype)allocWithZone:(struct _NSZone *)zone {
    if (!_defaultManager) {
        static dispatch_once_t onceToken;
        dispatch_once(&onceToken, ^{
            _defaultManager = [super allocWithZone:zone];
        });
    }
    return _defaultManager;
}
- (id)copyWithZone:(NSZone *)zone{
    return _defaultManager;
}
- (id)mutableCopyWithZone:(NSZone *)zone{
    return _defaultManager;
}

原型模式

以一個(gè)已經(jīng)創(chuàng)建的實(shí)例作為原型乡数,通過復(fù)制該原型對(duì)象來創(chuàng)建出對(duì)象椭蹄,在使用對(duì)象時(shí),使用者無需關(guān)心對(duì)象創(chuàng)建的細(xì)節(jié)净赴。在iOS開發(fā)中:copy 方法就是對(duì)原型設(shè)計(jì)模式的一種實(shí)現(xiàn)绳矩。主要是提供了一種大量創(chuàng)建復(fù)雜對(duì)象的方法。

重構(gòu)前

import Foundation
class Computer {
    var cpu: String
    var host: String
    var screen: String
    var uuid: String
    init(cpu: String, host: String, screen: String) {
        self.cpu = cpu
        self.host = host
        self.screen = screen
        self.uuid = UUID().uuidString
    }
    func logUUID() {
        print(uuid)
    }
}
let computer1 = Computer(cpu: "Intel core i7 7700K", host: "GY088-GDF-60", screen: "3008 x 1692")
computer1.logUUID()

此時(shí)若希望創(chuàng)建一臺(tái)相同配置的電腦則只能使用重復(fù)的創(chuàng)建方法

let computer2 = Computer(cpu: "Intel core i7 7700K", host: "GY088-GDF-60", screen: "3008 x 1692")

重構(gòu)后

import Foundation
class Computer {
    ...
    
    func copy() -> Computer {
        return Computer(cpu: self.cpu, host: self.host, screen: self.screen)
    }
}

新增一個(gè) copy() 方法玖翅,此時(shí)再創(chuàng)建相同配置的電腦只需調(diào)用原型的 copy() 方法即可翼馆,省去了配件的創(chuàng)建過程。
使用原型模式金度,一旦第一個(gè)對(duì)象被創(chuàng)建应媚,后面的對(duì)象創(chuàng)建都將變得非常容易。其中猜极,作為模板對(duì)象被稱為原型中姜,創(chuàng)建出來的對(duì)象擁有和模板對(duì)象一致的屬性和方法。

工廠方法模式

工廠方法設(shè)計(jì)模式注重于將對(duì)象的創(chuàng)建過程封閉起來跟伏,通過定義抽象的工廠接口和商品接口來隱藏負(fù)責(zé)對(duì)象創(chuàng)建的具體類

對(duì)上述 Computer 類進(jìn)行重構(gòu)

重構(gòu)后

enum Level {
    case low
    case high
}
protocol ComputerFactoryProtol {
    static func getComputer(level: Level) -> ComputerProtol
}
protocol ComputerProtol {
    var cpu: String { get }
    var host: String { get }
    var screen: String { get }
    var uuid: String { get }
    func logUUID()
}
class Computer: ComputerProtol {
    var cpu: String
    var host: String
    var screen: String
    var uuid: String
    init(cpu: String, host: String, screen: String) {
        self.cpu = cpu
        self.host = host
        self.screen = screen
        self.uuid = UUID().uuidString
    }
    func logUUID() {
        print(uuid)
    }
}
class ComputerFactory: ComputerFactoryProtol {
    static func getComputer(level: Level) -> ComputerProtol {
        switch level {
        case .low:
            return Computer(cpu: "Intel core i5 3300K", host: "GY088-GDF-10", screen: "1920 x 1080")
        case .high:
            return Computer(cpu: "Intel core i7 7700K", host: "GY088-GDF-60", screen: "3008 x 1692")
        }
    }
}

引入的 ComputerFactory 即工廠設(shè)計(jì)模式的具體體現(xiàn)扎筒,外界不再指明具體的配置信息,只需要根據(jù) level 即可創(chuàng)建指定配置的 Computer酬姆,
創(chuàng)建高配電腦嗜桌,例如:

let computer3 = ComputerFactory.getComputer(level: .high)

如果新增加了一種創(chuàng)建方式完全不同的計(jì)算機(jī),我們只需要新建一個(gè)遵守 ComputerProtol 的計(jì)算機(jī)類辞色,之后在 ComputerFactory 中統(tǒng)一處理這種新增的計(jì)算機(jī)類型即可骨宠,對(duì)使用者完全隱藏。

抽象工廠模式

抽象工廠是對(duì)工廠模式的一種升級(jí)相满,核心思路是為各種類型的對(duì)象提供一組統(tǒng)一的創(chuàng)建接口层亿,使用者無需關(guān)心這些對(duì)象具體是如何創(chuàng)建的。

還是上述代碼立美,若我們工廠方法即生產(chǎn) Computer 又可以生產(chǎn) TV

重構(gòu)后

enum Level {
    case low
    case high
}
protocol ComputerFactoryProtol {
    static func getComputer(level: Level) -> ComputerProtol
    static func getTV() -> TVProtol
}
protocol TVProtol {
    var name: String { get }
    func logName()
}
class TV: TVProtol {
    var name: String
    init(name: String) {
        self.name = name
    }
    func logName() {
        print(self.name)
    }
}
protocol ComputerProtol {
    ...
}
class Computer: ComputerProtol {
    ...    
}
class ComputerFactory: ComputerFactoryProtol {
    static func getTV() -> TVProtol {
        return TV(name: "海爾")
    }
    static func getComputer(level: Level) -> ComputerProtol {
        ...
    }
}

重構(gòu)后工廠類可以創(chuàng)建不同的對(duì)象匿又,對(duì)于使用者無需關(guān)心創(chuàng)建的細(xì)節(jié),抽象工廠將對(duì)象的創(chuàng)建和使用進(jìn)行了完全分離建蹄。

建造者模式

建造者模式用于復(fù)雜對(duì)象的創(chuàng)建碌更,使代碼聚合性更強(qiáng)裕偿,邏輯更加清晰。建造者模式通常與工程模式配合使用痛单,工廠著重于對(duì)象的創(chuàng)建嘿棘,建造者著重于創(chuàng)建復(fù)雜對(duì)象過程中組成對(duì)象的每一部分創(chuàng)建和最終組裝。
核心在于將復(fù)雜的對(duì)象拆解成多個(gè)簡單對(duì)象旭绒,通過一步步構(gòu)建簡單對(duì)象最終組合成復(fù)雜對(duì)象鸟妙。

重構(gòu)后

enum Foodtype {
    case a
    case b
}
enum Drink {
    case cola
    case juice
}
enum Staple {
    case hamburger
    case chickenRoll
}
class FoodPackage {
    var drink: Drink?
    var staple: Staple?
}
class BuildA {
    var foodPackage = FoodPackage()
    func build() -> FoodPackage {
        foodPackage.drink = .cola
        foodPackage.staple = .hamburger
        return foodPackage
    }
}
class BuildB {
    var foodPackage = FoodPackage()
    func build() -> FoodPackage {
        foodPackage.drink = .juice
        foodPackage.staple = .chickenRoll
        return foodPackage
    }
}
class FoodFactory {
    static func buildFood(type: Foodtype) -> FoodPackage {
        switch type {
        case .a:
            return BuildA().build()
        case .b:
            return BuildB().build()
        }
    }
}
let foodPackage = FoodFactory.buildFood(type: .a)

其中,一個(gè)完整的套餐對(duì)象由飲料對(duì)象挥吵、主食對(duì)象組成重父,FoodFactory 為工廠方法,其中根據(jù)套餐類型創(chuàng)建不同的套餐對(duì)象忽匈,具體的套餐對(duì)象的組成則是由 BuildABuildB 來完成房午。 BuildABuildB 是建造者模式的核心類,充當(dāng)建造者的角色脉幢。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末歪沃,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子嫌松,更是在濱河造成了極大的恐慌沪曙,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,194評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件萎羔,死亡現(xiàn)場(chǎng)離奇詭異液走,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)贾陷,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,058評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門缘眶,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人巷懈,你說我怎么就攤上這事』藕椋” “怎么了顶燕?”我有些...
    開封第一講書人閱讀 156,780評(píng)論 0 346
  • 文/不壞的土叔 我叫張陵,是天一觀的道長冈爹。 經(jīng)常有香客問我涌攻,道長,這世上最難降的妖魔是什么频伤? 我笑而不...
    開封第一講書人閱讀 56,388評(píng)論 1 283
  • 正文 為了忘掉前任恳谎,我火速辦了婚禮,結(jié)果婚禮上憋肖,老公的妹妹穿的比我還像新娘因痛。我一直安慰自己婚苹,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,430評(píng)論 5 384
  • 文/花漫 我一把揭開白布婚肆。 她就那樣靜靜地躺著租副,像睡著了一般坐慰。 火紅的嫁衣襯著肌膚如雪较性。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,764評(píng)論 1 290
  • 那天结胀,我揣著相機(jī)與錄音赞咙,去河邊找鬼。 笑死糟港,一個(gè)胖子當(dāng)著我的面吹牛攀操,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播秸抚,決...
    沈念sama閱讀 38,907評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼速和,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了剥汤?” 一聲冷哼從身側(cè)響起颠放,我...
    開封第一講書人閱讀 37,679評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎吭敢,沒想到半個(gè)月后碰凶,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,122評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡鹿驼,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,459評(píng)論 2 325
  • 正文 我和宋清朗相戀三年欲低,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片畜晰。...
    茶點(diǎn)故事閱讀 38,605評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡砾莱,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出凄鼻,到底是詐尸還是另有隱情腊瑟,我是刑警寧澤,帶...
    沈念sama閱讀 34,270評(píng)論 4 329
  • 正文 年R本政府宣布野宜,位于F島的核電站扫步,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏匈子。R本人自食惡果不足惜河胎,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,867評(píng)論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望虎敦。 院中可真熱鬧游岳,春花似錦政敢、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,734評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至访锻,卻和暖如春褪尝,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背期犬。 一陣腳步聲響...
    開封第一講書人閱讀 31,961評(píng)論 1 265
  • 我被黑心中介騙來泰國打工河哑, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人龟虎。 一個(gè)月前我還...
    沈念sama閱讀 46,297評(píng)論 2 360
  • 正文 我出身青樓璃谨,卻偏偏與公主長得像,于是被迫代替她去往敵國和親鲤妥。 傳聞我的和親對(duì)象是個(gè)殘疾皇子佳吞,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,472評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容