在iOS中理解設(shè)計(jì)模式

設(shè)計(jì)模式即編碼的工程化歉甚,是代碼設(shè)計(jì)經(jīng)驗(yàn)的總結(jié)皂吮。使用設(shè)計(jì)模式可提高代碼的復(fù)用性筋夏、可讀性和可靠性蒂胞。設(shè)計(jì)模式在各類面向?qū)ο蟮恼Z言中基本相通,僅在具體的實(shí)現(xiàn)語法上略有差異条篷,下面我們以O(shè)C為例來理解和研究一些常用的設(shè)計(jì)模式骗随。


單例模式

保證程序運(yùn)行中,一個(gè)類全局只有一個(gè)實(shí)例赴叹。它提供了對(duì)類對(duì)象的全局訪問點(diǎn)鸿染,在整個(gè)過程中共享著一份資源。

應(yīng)用:登錄控制體系稚瘾、網(wǎng)絡(luò)請(qǐng)求牡昆、音樂播放、分享體系等摊欠。

+ (instancetype)sharedInstance {

? ? ? static Singleton *singleton = nil;

? ? ? static dispatch_once_t onceToken;

? ? ? dispatch_once(&onceToken, ^{

? ? ? ? ? ? singleton = [[Singleton alloc] init];

? ? ? });

? ? ? return singleton;?

}

//嚴(yán)謹(jǐn)情況下應(yīng)把copyWithZone和mutableCopyWithZone也重寫

注:可將allocWithZone重寫為dispatch_once實(shí)現(xiàn)單例丢烘,sharedInstance中調(diào)用默認(rèn)的alloc init(alloc會(huì)默認(rèn)調(diào)用allocWithZone),此時(shí)些椒,單例可被繼承播瞳,重寫init方法實(shí)現(xiàn)子單例的擴(kuò)展。如下:

static Singleton *_instance;

+ (id)allocWithZone:(struct _NSZone *)zone {

? ? ? static dispatch_once_t onceToken;

? ? ? dispatch_once(&onceToken, ^{

? ? ? ? ? ? _instance = [super allocWithZone:zone];

? ? ? )};

? ? ? return _instance;

}

+ (instancetype)sharedInstance {

? ? ? ?if(!_instance) {

? ? ? ? ? ? ?_instance = [[Singleton alloc] init];

? ? ? ? }

? ? ? ? return _instance;

}

使用帶參數(shù)的宏定義可以把單例模式的聲明優(yōu)化到只寫一次免糕,在各單例類中的.h赢乓、.m中只需調(diào)用宏定義即可。

最后補(bǔ)充一下iOS系統(tǒng)的單例類:UIApplication石窑,UIScreen牌芋,NSNotificationCenter,NSFileManager松逊,NSUserDefaults躺屁,NSURLCache,NSHTTPCookieStorage等经宏。

工廠模式

簡單工廠模式

一個(gè)工廠類犀暑,根據(jù)傳入?yún)?shù)不同,決定初始化某個(gè)具體產(chǎn)品實(shí)例烁兰。

應(yīng)用理解:一個(gè)簡單四則運(yùn)算計(jì)算器耐亏。如果不使用工廠模式,要實(shí)現(xiàn)加減乘除四個(gè)方法就需要new4個(gè)運(yùn)算方法類沪斟,這顯然不是一個(gè)完美的解決方案广辰。此時(shí),若有個(gè)產(chǎn)品基類BaseCalculate,它包括加減乘除四個(gè)產(chǎn)品類(Add择吊,Minus袱耽,Multiply,Devide)干发,在需要實(shí)例化運(yùn)算對(duì)象的地方,使用運(yùn)算工廠類CalcuteFactory史翘,根據(jù)類型返回產(chǎn)品類的方法-(BaseCaculate *)createWithType:(id)type;生成對(duì)應(yīng)運(yùn)算的產(chǎn)品類對(duì)象枉长。

簡單工廠模式

缺點(diǎn):增加或者修改產(chǎn)品類時(shí),需在代碼層次修改工廠類(此時(shí)需重新測(cè)試工廠類)琼讽,不夠靈活必峰,不便擴(kuò)展。

為解決上述缺點(diǎn)钻蹬,出現(xiàn)了第二種工廠模式:

工廠方法模式

一個(gè)工廠類吼蚁,一個(gè)產(chǎn)品類對(duì)應(yīng)一個(gè)工廠子類(產(chǎn)品與工廠配套),即问欠,擴(kuò)展產(chǎn)品類別時(shí)需同時(shí)擴(kuò)展工廠子類肝匆,與簡單工廠模式相比,抽象了工廠類顺献。工廠子類中重寫抽象工廠類中的方法生產(chǎn)對(duì)應(yīng)的產(chǎn)品子類旗国。

工廠方法模式

缺點(diǎn)顯而易見:大量的產(chǎn)品+工廠類,且產(chǎn)品和工廠間隔斷嚴(yán)重?zé)o法復(fù)用相同代碼注整。

于是抽象工廠模式應(yīng)運(yùn)而生:

抽象工廠模式

抽象工廠模式的最大特點(diǎn)就是有多個(gè)抽象產(chǎn)品類能曾。找出某類產(chǎn)品的共性,設(shè)計(jì)出此類產(chǎn)品的抽象類(派生出多個(gè)具體產(chǎn)品類)肿轨。而其具有一個(gè)抽象工廠類和多個(gè)具體工廠類寿冕,每個(gè)具體工廠類都可創(chuàng)建多個(gè)具體產(chǎn)品類。

抽象工廠模式

觀察者模式

發(fā)布(publish)- 訂閱(Subscribe)模式椒袍,用于一對(duì)多依賴關(guān)系中的解耦驼唱。對(duì)象可以通過注冊(cè),成為觀察者(Observer)槐沼,去訂閱中心對(duì)象(Subject)的變化曙蒸。Subject(被觀察者)則需要實(shí)現(xiàn)觀察者注冊(cè)、數(shù)據(jù)更新通知岗钩、觀察者移除三個(gè)基礎(chǔ)方法纽窟。

NSNotification

注冊(cè)觀察者

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(notice:) name:@"PostName" object:nil];

- (void)notice:(id)sender { NSLog(@"%@",sender); }

被觀察者發(fā)出通知

[[NSNotificationCenterdefaultCenter] postNotificationName:@"PostName" object:nil];

移除通知

- (void)dealloc ?{

? ? ? [[NSNotificationCenter defaultCenter] removeObserver:self name:@"PostName" object:nil];

}

KVO

KVC、KVO小結(jié)和應(yīng)用


代理模式

OC和Swift中的protocol

非正式協(xié)議

即Category兼吓,如NSString (StringFrame)臂港。

代理與Block

1、block是讓代碼塊以閉包(一個(gè)函數(shù)+其執(zhí)行的外部上下文變量)的形式傳遞內(nèi)容,實(shí)在是太輕量級(jí)了审孽,適用于大多數(shù)異步和簡單的回調(diào)县袱。

2、當(dāng)有多個(gè)方法回調(diào)時(shí)應(yīng)當(dāng)選用delegate會(huì)更清晰佑力,如UITableView的delegate代理方法式散。

3、block會(huì)涉及到棧區(qū)到堆區(qū)的拷貝等操作打颤,delegate只是定義了一個(gè)方法列表暴拄,在遵守了協(xié)議的對(duì)象的objc_protocol_list中添加了一個(gè)節(jié)點(diǎn),運(yùn)行時(shí)向?qū)ο蟀l(fā)送消息即可编饺。所以block在時(shí)間空間消耗都大于delegate乖篷,性能消耗較大。

4透且、代理更加面向過程撕蔼,block更加面向結(jié)果。


策略模式

#結(jié)合現(xiàn)金支付計(jì)算策略實(shí)例詳細(xì)說明#

1秽誊、定義一個(gè)抽象的鲸沮、通用的算法(抽象策略類BaseStrategy)協(xié)議,此角色給出所有具體策略類所需的接口养距;

@protocol CashBase?

-(CGFloat)acceptCash:(CGFloat)cash;

@end

2诉探、讓每個(gè)具體算法(繼承Base的具體策略類NormalStrategy,SpecialStrategy)都遵循他的守則棍厌,提供了具體的算法實(shí)現(xiàn)了抽象策略類定義的接口肾胯;

@interface CashNormal : NSObject <CashBase>

@end

@implementation CashNormal

-(CGFloat)acceptCash:(CGFloat)cash { return cash; }

@end

@interface CaseReturn : NSObject <CashBase>

-(instancetype)initWithMoneyReturn:(CGFloat)moneyReturn;

@end

@implementation CaseReturn ? ??

-(instancetype)initWithMoneyReturn:(CGFloat)moneyReturn {

? ? ? if (self) {

? ? ? ? ? ?_moneyReturn = moneyReturn;

? ? ? }

? ? ? return self;

}

-(CGFloat)acceptCash:(CGFloat)cash {

? ? ? return cash - self.moneyReturn;

}

@end

3、然后需要定義一個(gè)環(huán)境角色(Context類)用來持有一個(gè)Strategy的引用耘纱,配合簡單工廠模式敬肚,根據(jù)入?yún)Q定調(diào)用哪個(gè)具體策略類算法;

@interface CashContext : NSObject

-(instancetype)initWithCashType:(CashType)type;

-(CGFloat)getResult:(CGFloat)money;

@end

@implementation CashContext

-(instancetype)initWithCashType:(CashType)type{

? ? ? //根據(jù)type初始化算法實(shí)例

}

-(CGFloat)getResult:(CGFloat)money{

? ? ? //算法實(shí)例調(diào)用策略接口

? ? ? return [self.cashSuper acceptCash:money];

}

@end

4束析、最后在需要的地方調(diào)用Context對(duì)象艳馒。

CashContext * context = [[CashContext alloc] initWithCashType:CashTypeNormal];

NSLog(@"結(jié)果是%f",[context getResult:100]);


裝飾模式

不修改原類代碼的情況下,動(dòng)態(tài)员寇、透明的給一個(gè)對(duì)象增加新的行為和職責(zé)弄慰,Decorator比生成子類更加靈活,其目的是把功能分散蝶锋,運(yùn)行期間再動(dòng)態(tài)組合陆爽。

裝飾器的構(gòu)成:1、Component扳缕,抽象的組件父類慌闭,聲明了一些方法由子類進(jìn)行重載别威;ConcreteComponent,具體的組件類驴剔,實(shí)現(xiàn)了組件接口省古,通常是被裝飾的原始對(duì)象。

2丧失、Decorator豺妓,裝飾器父類(Component細(xì)化后的抽象類),用來持有原對(duì)象(被裝飾對(duì)象)布讹。ConcreteDecorator具體的裝飾器類科侈,具體實(shí)現(xiàn)要添加的功能,并內(nèi)嵌Component操作炒事,以裝飾具體的組件對(duì)象。

在iOS中蔫慧,分類(category)簡單便捷的實(shí)現(xiàn)了裝飾器設(shè)計(jì)模式所能達(dá)到的功能挠乳,但嚴(yán)格意義上講并不符合裝飾器模式的定義。

注:1姑躲、有些教程中說委托也是iOS中的一種裝飾器模式睡扬,但我認(rèn)為委托沒有做到裝飾模式定義中“不修改原類代碼”的要求;2黍析、分類中定義的方法不要和原有類的方法重名卖怜。


軟件開發(fā)中還用很多常用的設(shè)計(jì)模式,如模板方法模式(提取算法可復(fù)用結(jié)構(gòu)阐枣,延遲某些特定步驟到子類:如問答題的不變部分(題目)和變化部分(答案))马靠、外觀模式(為一套需要同時(shí)調(diào)用的子系統(tǒng)定義一個(gè)高層的綜合接口,便于多個(gè)接口同時(shí)調(diào)用)蔼两、建造者模式甩鳄、狀態(tài)模式、適配器模式额划、備忘錄模式妙啃、組合模式、迭代器模式俊戳、單列模式揖赴、橋接模式、命令模式抑胎、職責(zé)鏈模式燥滑、中介者模式、享元模式圆恤、解釋器模式突倍、訪問者模式腔稀、原型模式(已有對(duì)象深拷貝申請(qǐng)新內(nèi)存,生成新對(duì)象羽历,需滿足NSCopying協(xié)議)等焊虏。

最后提供一下容易亂入的MVC,MVVM等設(shè)計(jì)模式等鏈接秕磷,嚴(yán)格來說诵闭,它們應(yīng)稱為架構(gòu)設(shè)計(jì)模式,而非廣義上的編碼設(shè)計(jì)模式澎嚣。

架構(gòu)設(shè)計(jì)模式之MVC和MVVM


寫在最后

沒有最后 <( ̄︶ ̄)>

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末疏尿,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子易桃,更是在濱河造成了極大的恐慌褥琐,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,284評(píng)論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件晤郑,死亡現(xiàn)場(chǎng)離奇詭異敌呈,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)造寝,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,115評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門磕洪,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人诫龙,你說我怎么就攤上這事析显。” “怎么了签赃?”我有些...
    開封第一講書人閱讀 164,614評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵谷异,是天一觀的道長。 經(jīng)常有香客問我锦聊,道長晰绎,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,671評(píng)論 1 293
  • 正文 為了忘掉前任括丁,我火速辦了婚禮荞下,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘史飞。我一直安慰自己尖昏,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,699評(píng)論 6 392
  • 文/花漫 我一把揭開白布构资。 她就那樣靜靜地躺著抽诉,像睡著了一般。 火紅的嫁衣襯著肌膚如雪吐绵。 梳的紋絲不亂的頭發(fā)上迹淌,一...
    開封第一講書人閱讀 51,562評(píng)論 1 305
  • 那天河绽,我揣著相機(jī)與錄音,去河邊找鬼唉窃。 笑死耙饰,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的纹份。 我是一名探鬼主播苟跪,決...
    沈念sama閱讀 40,309評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼蔓涧!你這毒婦竟也來了件已?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,223評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤元暴,失蹤者是張志新(化名)和其女友劉穎篷扩,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體茉盏,經(jīng)...
    沈念sama閱讀 45,668評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡瞻惋,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,859評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了援岩。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,981評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡掏导,死狀恐怖享怀,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情趟咆,我是刑警寧澤添瓷,帶...
    沈念sama閱讀 35,705評(píng)論 5 347
  • 正文 年R本政府宣布,位于F島的核電站值纱,受9級(jí)特大地震影響鳞贷,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜虐唠,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,310評(píng)論 3 330
  • 文/蒙蒙 一搀愧、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧疆偿,春花似錦咱筛、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,904評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至处铛,卻和暖如春饲趋,著一層夾襖步出監(jiān)牢的瞬間拐揭,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,023評(píng)論 1 270
  • 我被黑心中介騙來泰國打工奕塑, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留堂污,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,146評(píng)論 3 370
  • 正文 我出身青樓爵川,卻偏偏與公主長得像敷鸦,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子寝贡,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,933評(píng)論 2 355

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

  • 設(shè)計(jì)模式匯總 一扒披、基礎(chǔ)知識(shí) 1. 設(shè)計(jì)模式概述 定義:設(shè)計(jì)模式(Design Pattern)是一套被反復(fù)使用、多...
    MinoyJet閱讀 3,947評(píng)論 1 15
  • 一圃泡、設(shè)計(jì)模式的分類 總體來說設(shè)計(jì)模式分為三大類: 創(chuàng)建型模式碟案,共五種:工廠方法模式、抽象工廠模式颇蜡、單例模式价说、建造者...
    RamboLI閱讀 749評(píng)論 0 1
  • 一、設(shè)計(jì)模式的分類 總體來說設(shè)計(jì)模式分為三大類: 創(chuàng)建型模式风秤,共五種:工廠方法模式鳖目、抽象工廠模式、單例模式缤弦、建造者...
    lichengjin閱讀 894評(píng)論 0 8
  • 原文鏈接:http://blog.csdn.net/zhangerqing http://www.cnblogs....
    孤獨(dú)雜貨鋪閱讀 1,516評(píng)論 0 3
  • 設(shè)計(jì)模式基本原則 開放-封閉原則(OCP)领迈,是說軟件實(shí)體(類、模塊碍沐、函數(shù)等等)應(yīng)該可以拓展狸捅,但是不可修改。開-閉原...
    西山薄涼閱讀 3,798評(píng)論 3 14