設計模式(三)----中介者模式、觀察者模式、訪問者模式、策略模式、責任鏈模式

中介者模式

在一些很多對象之間會存在一定的交互,例如像即時聊天軟件中的語言視頻通話,這種就有很多的界面變化、如呼入中、呼出中、通話中、視頻中、免提,等等多種UI狀態,點擊相應的按鈕,界面其它的UI元素也會隨之改變。我們就可以使用中介者模式,進行統一管理、統一調度。同樣的在iOSAPP中我們的控制器界面也同樣可以使用這種管理模式,例如我們的界面控制單元有啟動頁、登錄頁、主頁面另外還可以有廣告頁,我們就可以使用一個主控制器來統一管理分配改展示什么頁面。

中介者模式類圖:


中介者模式類圖.png

圖中我們可以通過RootViewController來統一調度頁面的展示在APP上。

UniversalApp模型的實現

- (void)loadLaunchViewController
{
    [self addChildViewController:_launchVc];
}
- (void)loadLoginViewController
{
    [self addChildViewController:_loginVc];
}
- (void)loadMainViewController
{
    [self addChildViewController:_mainVc];
}

本節工程示例

觀察者模式

當一個對象的狀態和信息發生改變的時候,其它許多和它相關的對象也需要作出相應的變化的場景時,我們就可以使用觀察者模式。就像訂閱報紙一樣,我需要報紙就先訂閱,然后新的期刊到來時,就會收到新來的報紙。觀察者模式

觀察者模式類圖:


觀察者模式類圖.png

SubjectCenter的實現

static SubjectCenter *center = nil;

+ (instancetype)sharedInstance{
    static dispatch_once_t once;
    dispatch_once(&once, ^{
        center = [[SubjectCenter alloc] init];
    });
    return center;
}

- (instancetype)init
{
    self = [super init];
    if (self) {
        _bookCenter = [NSMutableDictionary dictionary];
    }
    return self;
}

// 創建書刊訂閱號
- (void)creatNumber:(NSString *)subNumber {
    NSMutableArray *arr = [self existNumber:subNumber];
    if (arr == nil) {
        arr = [NSMutableArray array];
        [_bookCenter setObject:arr forKey:subNumber];
    }
}

// 移除訂閱號
- (void)removeNumber:(NSString *)subNumber {
    NSMutableArray *arr = [self existNumber:subNumber];
    if (arr == nil) {
        arr = [NSMutableArray array];
        [_bookCenter removeObjectForKey:subNumber];
    }
}

// 添加用戶
- (void)addUser:(id <ObserveProtocol>)user wihtNumber:(NSString *)userNumber {
    NSMutableArray *arr = [self existNumber:userNumber];
    [arr addObject:user];
}

// 移除用戶
- (void)removeUser:(id <ObserveProtocol>)user withNumber:(NSString *)userNumber {
    NSMutableArray *arr = [self existNumber:userNumber];
    [arr removeObject:user];
}

// 發送消息
- (void)sendMessage:(id)message withSubNumber:(NSString *)userNumber {
    NSMutableArray *arr = [self existNumber:userNumber];
    if (arr) {
        
        for (id<ObserveProtocol> observe in arr) {
            if ([observe respondsToSelector:@selector(subMessage:withSubNumber:)]) {
                [observe subMessage:message withSubNumber:userNumber];
            }
        }
        
    }
}

- (NSMutableArray *)existNumber:(NSString *)subStringNumber {
    return [_bookCenter objectForKey:subStringNumber];
}

在iOS的系統中,我們常用的有通知模式和鍵值編碼的形式,前者以廣播形式發送特定的消息,而后者則是被觀察的對象直接向觀察者發送通知,綁定特定對象屬性的值。

本節工程示例

訪問者模式

在一些對象結構中,如果要對其中的對象進行很多不相關操作的時候,又不想讓這些操作迫使這些對象的類混亂,我們便可以將這些操作集中起來,定義在一個訪問者類中,并在訪問者中定義的操作使用它。對這些對象進行依賴一些的具體類型的操作還有添加新的操作都可以使用這種訪問者模式。也就是在不改變各元素類的前提下定義作用于這些元素的新操作。例如我們的開發者有安卓開發和iOS開發者,分別進行OA簽到和Git上傳代碼,就可以使用訪問者模式,去相關服務器進行操作而不改變服務器。訪問者模式用盡可能的修改,可以把組合結構與其他的訪問者類中的相關算法分離。

訪問者模式類圖:


訪問者模式類圖.png

實例代碼中實現了iOS開發者訪問OA服務器的簽到和Git服務器的下載代碼功能。
其中GitWebsite的實現

- (void)acceptDeveloper:(Developer *)developer
{
    [self doSomething];
}

- (void)doSomething
{
    NSLog(@"下載iOS代碼");
}

本節工程示例

策略模式

在開發中我們往往根據不同情況使用不同的算法,一般會使用if-else或者switch-case條件語句來進行判斷,如果算法過多的話往往比較復雜并且難以維護。這個時候將不同的算法一個個的封裝起來,并使他們可以相互替換,就可以避免了多重條件的判斷,并且擁有良好的擴展性。例如我們出去旅游,有多種旅行方式,我們把每種出行方式封裝成單獨的一個對象來實現。

策略模式類圖:


策略模式類圖.png

TravelStrategy根據不同的算法接口,實現不同的出行方式。

TravelStrategy的實現

- (id)initWithTravelStrategy:(TravelStrategy *)strategy
{
    self = [super init];
    if (self) {
        _strategy = strategy;
    }
    return self;
}

- (void)travel
{
    [_strategy travel];
}


本節工程示例

責任鏈模式

在一些有多個對象可以處理請求,而處理只有在運行的時候才能確定的場景下,包括向一組對象發出請求,又不想顯示的指定處理請求的特定處理程序的場景下,我們就可以使用責任鏈模式進行程序設計。這使得多個對象都有機會處理請求,也避免了發送者和接收者之間發生耦合。這種模式將這些對象連成一條鏈,將請求沿著這條鏈傳遞,直到有一個對象處理為止。例如,在公司進行財務審批,組長能審批不大于1000的金額,超過的話交給經理來處理,但超過100000的話,只能交給老板來審批了。

責任鏈模式類圖:


責任鏈模式類圖.png

MemberModel定義了統一的接口,它的操作可以通過遞歸傳達到借點的每一處。

其中ApplyHander的實現

- (void)handleApplyMoneyCount:(NSInteger)moneyCount
{
    [self.nextHander handleApplyMoneyCount:moneyCount];
}

GroupLeaderHander的實現

- (void)handleApplyMoneyCount:(NSInteger)moneyCount
{
    if (moneyCount <= 1000) {
        NSLog(@"組長通過了審批");
    }else{
        [super handleApplyMoneyCount:moneyCount];
    }
}

ManagerHander的實現

- (void)handleApplyMoneyCount:(NSInteger)moneyCount
{
    if (moneyCount <= 10000) {
        NSLog(@"經歷通過了審批");
    }else{
        [super handleApplyMoneyCount:moneyCount];
    }
}

BossManager的實現

- (void)handleApplyMoneyCount:(NSInteger)moneyCount
{
    NSLog(@"老板通過了審批");
}

客戶端的調用

    NSInteger moneyCount = 99999;
    
    GroupLeaderHander *groupLeader = [[GroupLeaderHander alloc] init];
    ManagerHander *manager = [[ManagerHander alloc] init];
    BossManager *boss = [[BossManager alloc] init];
    
    groupLeader.nextHander = manager;
    manager.nextHander = boss;
    
    [groupLeader handleApplyMoneyCount:moneyCount];

本節工程示例

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • Spring Cloud為開發人員提供了快速構建分布式系統中一些常見模式的工具(例如配置管理,服務發現,斷路器,智...
    卡卡羅2017閱讀 134,881評論 18 139
  • 1 場景問題# 1.1 擴展客戶管理的功能## 考慮這樣一個應用:擴展客戶管理的功能。 既然是擴展功能,那么肯定是...
    七寸知架構閱讀 2,960評論 1 58
  • 常思剪燭西窗前,獨恨花開與月圓 黛玉荷鋤猶有助,我何孤立悲嬋娟!
    一路狂奔2008閱讀 314評論 0 0
  • 今天是雞年最冷的一天...... 氣溫達到了零下12°,出門的一瞬間就感覺被凍透了,但心情是高興的,因為已經周二了...
    此心安處是吾鄉AiMay閱讀 118評論 2 1
  • 長天烏云飛渡,河畔鴉落日暮,恰同學聚會,酒酣再舉躑躅,沉醉,沉醉,青春無語相佇。
    有坑的蘿卜閱讀 469評論 0 0