09-進(jìn)階之路-設(shè)計(jì)模式和六大設(shè)計(jì)原則

1.六大設(shè)置原則

學(xué)習(xí)鏈接

  1. 單一職責(zé)原則
    一個(gè)類只負(fù)責(zé)一件事,諸如UIView和Calayer
  2. 開閉原則
    對(duì)修改關(guān)閉,對(duì)擴(kuò)展開放恳守。諸如定義一個(gè)類,盡量考慮以后迭代的考慮剔蹋。
  3. 接口隔離原則
    使用多個(gè)專門的協(xié)議旅薄,不是一個(gè)辅髓。諸如UITableview的delegate和。UITableViewDataSource
  4. 依賴倒置原則
    抽象不應(yīng)該依賴具體實(shí)現(xiàn)少梁,具體實(shí)現(xiàn)可以依賴抽象
  5. 里氏替換原則(子類不影響父類)
    父類可以被子類無縫替換洛口。諸如KVO
  6. 迪米特法則(高內(nèi)聚,低耦合)
    一個(gè)對(duì)象對(duì)另一個(gè)對(duì)象盡可能少的了解凯沪。

2.責(zé)任鏈模式

任務(wù)執(zhí)行順序可以很方便的更改

#import <Foundation/Foundation.h>

@class BusinessObject;
typedef void(^CompletionBlock)(BOOL handled);
typedef void(^ResultBlock)(BusinessObject *handler, BOOL handled);

@interface BusinessObject : NSObject

// 下一個(gè)響應(yīng)者(響應(yīng)鏈構(gòu)成的關(guān)鍵)
@property (nonatomic, strong) BusinessObject *nextBusiness;
// 響應(yīng)者的處理方法
- (void)handle:(ResultBlock)result;

// 各個(gè)業(yè)務(wù)在該方法當(dāng)中做實(shí)際業(yè)務(wù)處理
- (void)handleBusiness:(CompletionBlock)completion;
@end
//----------------------實(shí)現(xiàn)文件--------------------
@implementation BusinessObject

// 責(zé)任鏈入口方法
- (void)handle:(ResultBlock)result
{
    CompletionBlock completion = ^(BOOL handled){
        // 當(dāng)前業(yè)務(wù)處理掉了第焰,上拋結(jié)果
        if (handled) {
            result(self, handled);
        }
        else{
            // 沿著責(zé)任鏈,指派給下一個(gè)業(yè)務(wù)處理
            if (self.nextBusiness) {
                [self.nextBusiness handle:result];
            }
            else{
                // 沒有業(yè)務(wù)處理, 上拋
                result(nil, NO);
            }
        }
    };
    
    // 當(dāng)前業(yè)務(wù)進(jìn)行處理
    [self handleBusiness:completion];
}

- (void)handleBusiness:(CompletionBlock)completion
{
    /*
     業(yè)務(wù)邏輯處理
     如網(wǎng)絡(luò)請(qǐng)求妨马、本地照片查詢等
     */
//    NSLog(@"  如網(wǎng)絡(luò)請(qǐng)求挺举、本地照片查詢等");
}

@end
//----------------------使用--------------------
//aBusinessObject集成 BusinessObject 重寫handleBusiness 方法
    BusinessObject *Aobject = [[aBusinessObject alloc] init];
    BusinessObject *Bobject = [[bBusinessObject alloc] init];
    BusinessObject *Cobject = [[cBusinessObject alloc] init];
    Aobject.nextBusiness = Bobject;
    Bobject.nextBusiness = Cobject;
    NSLog(@"%@  %@  %@",Aobject,Bobject,Cobject);

    [Aobject handle:^(BusinessObject *handler, BOOL handled) {
        NSLog(@"處理完成~~~~~~~~ %@  %d",handler,handled);

    }];

3.橋接的模式

解耦,


image
#import <Foundation/Foundation.h>
#import "BaseObjectB.h"
@interface BaseObjectA : NSObject

// 橋接模式的核心實(shí)現(xiàn)
@property (nonatomic, strong) BaseObjectB *objB;

// 獲取數(shù)據(jù)
- (void)handle;

@end

//----------------------實(shí)現(xiàn)文件--------------------
@implementation BaseObjectA

 /*
    A1 --> B1烘跺、B2湘纵、B3         3種
    A2 --> B1、B2滤淳、B3         3種
    A3 --> B1梧喷、B2、B3         3種
  */
- (void)handle
{
    // override to subclass
    
    [self.objB fetchData];
}

@end
//------------------------------------------
#import <Foundation/Foundation.h>

@interface BaseObjectB : NSObject

- (void)fetchData;

@end
//-------------------實(shí)現(xiàn)-----------------------
#import "BaseObjectB.h"

@implementation BaseObjectB

- (void)fetchData
{
    // override to subclass
}

@end

//-------------------使用現(xiàn)-----------------------

@interface BridgeDemo()
@property (nonatomic, strong) BaseObjectA *objA;
@end

@implementation BridgeDemo

/*
 根據(jù)實(shí)際業(yè)務(wù)判斷使用那套具體數(shù)據(jù)
 A1 --> B1、B2铺敌、B3         3種
 A2 --> B1汇歹、B2、B3         3種
 A3 --> B1偿凭、B2产弹、B3         3種
 */
- (void)fetch
{
    // 創(chuàng)建一個(gè)具體的ClassA
    _objA = [[ObjectA1 alloc] init];
    
    // 創(chuàng)建一個(gè)具體的ClassB
    BaseObjectB *b1 = [[ObjectB1 alloc] init];
    // 將一個(gè)具體的ClassB1 指定給抽象的ClassB
    _objA.objB = b1;
    
    // 獲取數(shù)據(jù)
    [_objA handle];
}

@end

4.適配器模式

對(duì)原有代碼不用調(diào)整

// 適配對(duì)象
@interface CoolTarget : NSObject

// 被適配對(duì)象
@property (nonatomic, strong) Target *target;

// 對(duì)原有方法包裝
- (void)request;

@end
//--------------------------------------
@implementation CoolTarget

- (void)request {
    // 額外處理
    [self.target operation];
    // 額外處理
}
@end

5.單例模式

@implementation Mooc

+ (id)sharedInstance
{
    // 靜態(tài)局部變量
    static Mooc *instance = nil;
    
    // 通過dispatch_once方式 確保instance在多線程環(huán)境下只被創(chuàng)建一次
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        // 創(chuàng)建實(shí)例
        instance = [[super allocWithZone:NULL] init];
    });
    return instance;
}

// 重寫方法【必不可少】
+ (id)allocWithZone:(struct _NSZone *)zone{
    return [self sharedInstance];
}

// 重寫方法【必不可少】
- (id)copyWithZone:(nullable NSZone *)zone{
    return self;
}

@end

6.命令模式

行為參數(shù)化、降低代碼重合度
需要一個(gè)管理者和一個(gè)命令(繼承使用)


#import <Foundation/Foundation.h>
#import "Command.h"
@interface CommandManager : NSObject
// 命令管理容器
@property (nonatomic, strong) NSMutableArray <Command*> *arrayCommands;

// 命令管理者以單例方式呈現(xiàn)
+ (instancetype)sharedInstance;

// 執(zhí)行命令
+ (void)executeCommand:(Command *)cmd completion:(CommandCompletionCallBack)completion;

// 取消命令
+ (void)cancelCommand:(Command *)cmd;

@end
//---------------------------------------
#import "CommandManager.h"

@implementation CommandManager

// 命令管理者以單例方式呈現(xiàn)
+ (instancetype)sharedInstance
{
    static CommandManager *instance = nil;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        instance = [[super allocWithZone:NULL] init];
    });
    return instance;
}

// 【必不可少】
+ (id)allocWithZone:(struct _NSZone *)zone{
    return [self sharedInstance];
}

// 【必不可少】
- (id)copyWithZone:(nullable NSZone *)zone{
    return self;
}

// 初始化方法
- (id)init
{
    self = [super init];
    if (self) {
        // 初始化命令容器
        _arrayCommands = [NSMutableArray array];
    }
    return self;
}

+ (void)executeCommand:(Command *)cmd completion:(CommandCompletionCallBack)completion
{
    if (cmd) {
        // 如果命令正在執(zhí)行不做處理弯囊,否則添加并執(zhí)行命令
        if (![self _isExecutingCommand:cmd]) {
            // 添加到命令容器當(dāng)中
            [[[self sharedInstance] arrayCommands] addObject:cmd];
            // 設(shè)置命令執(zhí)行完成的回調(diào)
            cmd.completion = completion;
            //執(zhí)行命令
            [cmd execute];
        }
    }
}

// 取消命令
+ (void)cancelCommand:(Command *)cmd
{
    if (cmd) {
        // 從命令容器當(dāng)中移除
        [[[self sharedInstance] arrayCommands] removeObject:cmd];
        // 取消命令執(zhí)行
        [cmd cancel];
    }
}

// 判斷當(dāng)前命令是否正在執(zhí)行
+ (BOOL)_isExecutingCommand:(Command *)cmd
{
    if (cmd) {
        NSArray *cmds = [[self sharedInstance] arrayCommands];
        for (Command *aCmd in cmds) {
            // 當(dāng)前命令正在執(zhí)行
            if (cmd == aCmd) {
                return YES;
            }
        }
    }
    return NO;
}
@end
//----------------------------------------------
@class Command;
typedef void(^CommandCompletionCallBack)(Command* cmd);

@interface Command : NSObject
@property (nonatomic, copy) CommandCompletionCallBack completion;

- (void)execute;
- (void)cancel;

- (void)done;

@end
//----------------------------------------------

#import "Command.h"
#import "CommandManager.h"
@implementation Command

- (void)execute{
    
    //override to subclass;
    [self done];
}

- (void)cancel{
    
    self.completion = nil;
}

- (void)done
{
    dispatch_async(dispatch_get_main_queue(), ^{
        
        if (_completion) {
            _completion(self);
        }
        
        //釋放
        self.completion = nil;
        
        [[CommandManager sharedInstance].arrayCommands removeObject:self];
    });
}

@end
//---------------------使用-------------------------
//Command 采用繼承重寫 execute 的方式
    Command *command1 = [[Command alloc] init];
    Command *command2 = [[Command alloc] init];
    Command *command3 = [[Command alloc] init];
    
    [CommandManager executeCommand:command1 completion:^(Command *cmd) {
        NSLog(@"1");
    }] ;
    
    [CommandManager executeCommand:command2 completion:^(Command *cmd) {
           NSLog(@"2");
    }] ;
    
    [CommandManager executeCommand:command3 completion:^(Command *cmd) {
           NSLog(@"3");
    }] ;
?著作權(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
  • 文/不壞的土叔 我叫張陵扇谣,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我闲昭,道長(zhǎ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
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(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ú)居荒郊野嶺守林人離奇死亡咱娶,尸身上長(zhǎng)有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
  • 正文 我出身青樓扇单,卻偏偏與公主長(zhǎng)得像商模,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子蜘澜,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,472評(píng)論 2 348

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

  • 設(shè)計(jì)模式之六大原則(轉(zhuǎn)載) 關(guān)于設(shè)計(jì)模式的六大設(shè)計(jì)原則的資料網(wǎng)上很多...
    霄霄霄霄閱讀 898評(píng)論 0 1
  • 轉(zhuǎn)載標(biāo)注聲明:http://www.uml.org.cn/sjms/201211023.asp 目錄:[設(shè)計(jì)模式六...
    Bloo_m閱讀 707評(píng)論 0 7
  • 設(shè)計(jì)模式六大原則 設(shè)計(jì)模式六大原則(1):?jiǎn)我宦氊?zé)原則 定義:不要存在多于一個(gè)導(dǎo)致類變更的原因施流。通俗的說,即一個(gè)類...
    viva158閱讀 764評(píng)論 0 1
  • 設(shè)計(jì)模式匯總 一鄙信、基礎(chǔ)知識(shí) 1. 設(shè)計(jì)模式概述 定義:設(shè)計(jì)模式(Design Pattern)是一套被反復(fù)使用瞪醋、多...
    MinoyJet閱讀 3,922評(píng)論 1 15
  • 一切讓你墮落的言論和陪伴 ,無論出于何種意圖装诡,都會(huì)在你的身上注入病毒趟章。人生路上,消極悲觀的話別聽慎王,自暴自棄的人別處...
    阿婷_TING閱讀 191評(píng)論 0 0