實(shí)例解析設(shè)計(jì)模式中的外觀模式在iOS App開(kāi)發(fā)中的運(yùn)用
外觀模式(Facade),為子系統(tǒng)中的一組接口提供一個(gè)一致的界面,此模式定義 一個(gè)高層接口,這個(gè)接口使得這一子系統(tǒng)更加容易使用。
下面給大家展示一下類(lèi)的結(jié)構(gòu)圖,想必大家一看就明白了:
其實(shí)這個(gè)模式中,沒(méi)有類(lèi)與類(lèi)之間的繼承關(guān)系,只是進(jìn)行了簡(jiǎn)單的類(lèi)引用,統(tǒng)一了對(duì)外的接口而已??雌饋?lái)是不是很簡(jiǎn)單?廢話(huà)不多說(shuō)了,下面簡(jiǎn)單向大家展示一下代碼吧!
注意:本文所有代碼均在ARC環(huán)境下編譯通過(guò)。
SubSystemOne類(lèi)接口
#import <Foundation/Foundation.h>
@interface SubSystemOne:NSObject
-(void)MethodOne;
@end
SubSystemOne類(lèi)實(shí)現(xiàn)
#import "SubSystemOne.h"
@implementation SubSystemOne
-(void)MethodOne{
NSLog(@"子系統(tǒng)方法一");
}
@end
SubSystemTwo類(lèi)接口
#import <Foundation/Foundation.h>
@interface SubSystemTwo:NSObject
-(void)MethodTwo;
@end
SubSystemTwo類(lèi)實(shí)現(xiàn)
#import "SubSystemTwo.h"
@implementation SubSystemTwo
-(void)MethodTwo{
NSLog(@"子系統(tǒng)方法二");
}
@end
SubSystemThree類(lèi)接口
#import <Foundation/Foundation.h>
@interface SubSystemThree:NSObject
-(void)MethodThree;
@end
SubSystemThree類(lèi)實(shí)現(xiàn)
#import "SubSystemThree.h"
@implementation SubSystemThree
-(void)MethodThree{
NSLog(@"子系統(tǒng)方法三");
}
@end
SubSystemFour類(lèi)接口
#import <Foundation/Foundation.h>
@interface SubSystemFour:NSObject
-(void)MethodFour;
@end
SubSystemFour類(lèi)實(shí)現(xiàn)
#import "SubSystemFour.h"
@implementation SubSystemFour
-(void)MethodFour{
NSLog(@"子系統(tǒng)方法四");
}
@end
Facade類(lèi)接口
#import<Foundation/Foundation.h>
@class SubSystemOne;//此處@class關(guān)鍵字的作用是聲明(不是定義哦)所引用的類(lèi)
@class SubSystemTwo;
@class SubSystemThree;
@class SubSystemFour;
@interface Facade :NSObject{
@private SubSystemOne *one;
@private SubSystemTwo *two;
@private SubSystemThree *three;
@private SubSystemFour *four;
}
-(Facade*)MyInit;
-(void)MethodA;
-(void)MethodB;
@end
Facade類(lèi)實(shí)現(xiàn)
#import "Facade.h"
#import "SubSystemOne.h"
#import "SubSystemTwo.h"
#import "SubSystemThree.h"
#import "SubSystemFour.h"
@implementation Facade
-(Facade*)MyInit{
one= [[SubSystemOne alloc]init];
two= [[SubSystemTwo alloc]init];
three= [[SubSystemThree alloc]init];
four= [[SubSystemFour alloc]init];
return self;
}
-(void)MethodA{
NSLog(@"\n方法組A() ---- ");
[one MethodOne];
[two MethodTwo];
[three MethodThree];
[four MethodFour];
}
-(void)MethodB{
NSLog(@"\n方法組B() ---- ");
[two MethodTwo];
[three MethodThree];
}
@end
Main()方法調(diào)用
#import <Foundation/Foundation.h>
#import "Facade.h"
int main (int argc,const char * argv[])
{
@autoreleasepool{
Facade *facade = [[Facade alloc]MyInit];
[facade MethodA];
[facade MethodB];
}
return 0;
}
在開(kāi)發(fā)軟件時(shí)候,考慮使用外觀模式的情況一般分為三種情況。第一種情況,設(shè)計(jì)初始階段,應(yīng)該要有意識(shí)的將不同的兩個(gè)分層分離,層與層之間建立外觀Facade,這樣可以為復(fù)雜的子系統(tǒng)提供一個(gè)簡(jiǎn)單的接口,使得耦合大大降低。第二種情況,在開(kāi)發(fā)階段子系統(tǒng)往往因?yàn)椴粩嗟闹貥?gòu)演化而變得越來(lái)越復(fù)雜,增加外觀Facade可以提供一個(gè)簡(jiǎn)單的接口,減少它們之間的依賴(lài)。第三種情況,在維護(hù)一個(gè)遺留的大型系統(tǒng)時(shí),可能這個(gè)系統(tǒng)已經(jīng)非常難以維護(hù)和擴(kuò)展了,如果有新的需求,那么可以為新系統(tǒng)開(kāi)發(fā)一個(gè)外觀Facade類(lèi),來(lái)提供設(shè)計(jì)粗糙或高度復(fù)雜的遺留代碼的比較清晰簡(jiǎn)單的接口,讓新系統(tǒng)與Facade對(duì)象交互,F(xiàn)acade與遺留代碼交互所有復(fù)雜的工作,這樣可以保持較低的耦合度。
實(shí)例進(jìn)階
目前你有 PersistencyManager 來(lái)在本地存儲(chǔ)專(zhuān)輯數(shù)據(jù),HTTPClient 處理遠(yuǎn)程通信。項(xiàng)目中其它的類(lèi)跟這些邏輯都沒(méi)關(guān)。
執(zhí)行這個(gè)模式,只有 LibraryAPI 來(lái)保存 PersistencyManager 和 HTTPClient 的實(shí)例。之后,LibraryAPI 將會(huì)公開(kāi)一個(gè)簡(jiǎn)單的 API 來(lái)訪(fǎng)問(wèn)這些服務(wù)。
LibraryAPI 將會(huì)公開(kāi)給其它代碼,但是它隱藏了 APP 中 HTTPClient 和 PersistencyManager 的復(fù)雜部分。
打開(kāi) LibraryAPI.h,在頂部引入面文件:
#import "Album.h"
接下來(lái),在 LibraryAPI.h下面添加如下方法:
- (NSArray*)getAlbums;
- (void)addAlbum:(Album*)album atIndex:(int)index;
- (void)deleteAlbumAtIndex:(int)index;
現(xiàn)在,這些方法都公開(kāi)給了其它類(lèi)。
在 LibraryAPI.m 文件引入如下兩個(gè)文件:
#import "PersistencyManager.h"
#import "HTTPClient.h"
只有在這個(gè)地方你才會(huì)需要引入這些類(lèi)。記?。耗愕?API 將會(huì)是你「復(fù)雜」系統(tǒng)的唯一的接入點(diǎn)。
現(xiàn)在添加一些私有屬性在你的類(lèi)的擴(kuò)展里(在 @implementation 上面)
@interface LibraryAPI () {
PersistencyManager *persistencyManager;
HTTPClient *httpClient;
BOOL isOnline;
}
@end
isOnline 用來(lái)判斷,如果專(zhuān)輯列表數(shù)據(jù)發(fā)生變化是否能夠更新到服務(wù)器,例如添加或者刪除專(zhuān)輯。
你現(xiàn)在需要在 init 方法中初始化這些變量,在 LibraryAPI.m 中添加下面代碼:
- (id)init
{
self = [super init];
if (self) {
persistencyManager = [[PersistencyManager alloc] init];
httpClient = [[HTTPClient alloc] init];
isOnline = NO;
}
return self;
}
這個(gè) HTTP 客戶(hù)端在這里并不真正的工作,它只是在外觀設(shè)計(jì)里面起一個(gè)示范用法的作用,所以 isOnline 永遠(yuǎn)是 NO 了。
接下來(lái),在 LibraryAPI.m 里面添加下面三個(gè)方法:
- (NSArray*)getAlbums
{
return [persistencyManager getAlbums];
}
- (void)addAlbum:(Album*)album atIndex:(int)index
{
[persistencyManager addAlbum:album atIndex:index];
if (isOnline)
{
[httpClient postRequest:@"/api/addAlbum" body:[album description]];
}
}
- (void)deleteAlbumAtIndex:(int)index
{
[persistencyManager deleteAlbumAtIndex:index];
if (isOnline)
{
[httpClient postRequest:@"/api/deleteAlbum" body:[@(index) description]];
}
}
看一下 addAlbum:atIndex:。這個(gè)類(lèi)首先更新本地?cái)?shù)據(jù),如果聯(lián)網(wǎng),它再更新遠(yuǎn)端服務(wù)器。這就是外觀設(shè)計(jì)的長(zhǎng)處;當(dāng)一些系統(tǒng)外的類(lèi)添加了一個(gè)新專(zhuān)輯,它不知道─也不需要知道─復(fù)雜的內(nèi)部系統(tǒng)。
提示:當(dāng)在你的子系統(tǒng)里設(shè)計(jì)一個(gè)外觀類(lèi)的時(shí)候,記住沒(méi)有任何東西可能阻止客戶(hù)訪(fǎng)問(wèn)這些「隱藏」類(lèi)。要多寫(xiě)些防御性的代碼,不要想當(dāng)然的認(rèn)為所有客戶(hù)都會(huì)用同樣的方式使用你的外觀類(lèi)。
運(yùn)行你的程序,你會(huì)看一個(gè)黑底空白內(nèi)容的屏幕,像下面這樣:
- iOS App開(kāi)發(fā)中使用設(shè)計(jì)模式中的單例模式的實(shí)例解析
- 詳解iOS應(yīng)用的設(shè)計(jì)模式開(kāi)發(fā)中Mediator中介者模式的使用
- iOS App設(shè)計(jì)模式開(kāi)發(fā)中對(duì)迭代器模式的使用示例
- iOS App的設(shè)計(jì)模式開(kāi)發(fā)中對(duì)State狀態(tài)模式的運(yùn)用
- 深入解析設(shè)計(jì)模式中的裝飾器模式在iOS應(yīng)用開(kāi)發(fā)中的實(shí)現(xiàn)
- iOS應(yīng)用運(yùn)用設(shè)計(jì)模式中的Strategy策略模式的開(kāi)發(fā)實(shí)例
- iOS App設(shè)計(jì)模式開(kāi)發(fā)中策略模式的實(shí)現(xiàn)示例
- IOS開(kāi)發(fā)中的設(shè)計(jì)模式匯總
相關(guān)文章
iOS11.3以下modal中input光標(biāo)錯(cuò)位的解決方法
這篇文章主要介紹了iOS11.3以下modal中input光標(biāo)錯(cuò)位的解決方法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-12-12iOS實(shí)現(xiàn)循環(huán)滾動(dòng)公告欄
這篇文章主要為大家詳細(xì)介紹了iOS實(shí)現(xiàn)循環(huán)滾動(dòng)公告欄,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-03-03iOS 10即將來(lái)襲!升級(jí)你的iOS開(kāi)發(fā)裝備
iOS 10來(lái)了!你必需的10款iOS開(kāi)發(fā)必備工具,讓你的開(kāi)發(fā)過(guò)程事半功倍2016-07-07iOS開(kāi)發(fā)之widget實(shí)現(xiàn)詳解
這篇文章主要為大家詳細(xì)介紹了iOS開(kāi)發(fā)之widget實(shí)現(xiàn),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-09-09詳解iOS多線(xiàn)程之2.NSThread的加鎖@synchronized
這篇文章主要介紹了詳解iOS多線(xiàn)程之2.NSThread的加鎖@synchronized,有需要的小伙伴可以參考下。2016-11-11