《iOS設計模式(1)簡單工廠模式》
《iOS設計模式(2)工廠模式》
《iOS設計模式(3)適配器模式》
《iOS設計模式(4)抽象工廠模式》
《iOS設計模式(5)策略模式》
《iOS設計模式(6)模板模式》
《iOS設計模式(7)建造者模式》
最近事情比較多,很長時間沒有更新文章了。正好今天有時間,我們看一下設計模式之外觀模式。
“為子系統中的一組接口提供一個統一的接口。外觀模式定義了一個更高層次的接口,這個接口使得這一子系統更加容易使用。” ----《設計模式》(Addison-Wesley,1994)
【注意:子系統可以是多個也可以是一個。】
(1)子系統類:每個子系統定義了相關功能和模塊的接口。
(2)Facade(外觀類):整合子系統中的接口,客戶端可以調用這個類的方法。
(3)Clients(客戶端):通過外觀類提供的接口和各個子系統的接口進行交互。
參考結構圖(來自百度百科)
在以下情況下可以考慮使用外觀模式:
(1)設計初期階段,應該有意識的將不同層分離,層與層之間建立外觀模式。
(2)開發階段,子系統越來越復雜,增加外觀模式提供一個簡單的調用接口。
(3)維護一個大型遺留系統的時候,可能這個系統已經非常難以維護和擴展,但又包含非常重要的功能,為其開發一個外觀類,以便新系統與其交互。百度百科
我們看一下具體的使用場景吧,還記得前面文章中我們提到買車的事吧,今天還是拿買車說事。前面我們選好了車,現在進入到買車的具體流程中。你從4S店買一輛車,幾乎要涉及到店裡的每個部門,比如財務部門、銷售部門、售後服務部門等等。
那麼問題來了,我們買一輛車真的就需要把4S店的每個部門都跑一邊嗎?其實沒必要,我們只要跟接待自己的銷售服務人員溝通好就行了,剩下的事情,她可以幫我們做。比如說:我們只要選好付款方式,然後去交錢就完事了,並不關心財務部門內部那些全款買車的流程和貸款買車的流程;也不用關心怎樣去銷售部門拿贈品;也不用關心售後服務部門誰來幫你做那些服務內容;這一切我們只要跟接待自己的銷售人員溝通就好了。
這個例子中4S店的各個部門其實就類似一個個的子系統,而接待我們的美女銷售就是外觀角色。下面我們看一下具體的代碼實現。
先看各個子系統的接口實現吧:
(1)LHFinance:財務部門管理:現金付款、申請貸款、審核貸款、放款等業務。
#import@interface LHFinance : NSObject // 現金支付 - (void)cashPayment; // 申請貸款 - (BOOL)applyLoan; // 審核貸款 - (BOOL)auditLoan; // 放款 - (BOOL)getLoad; @end
(2)銷售部門管理:車輛調配、配件、贈品等業務。
#import@interface LHSales : NSObject // 提車 - (void)provideCar; // 車貼膜 - (void)carFilm; // 行車記錄儀 - (void)tachograph; // 發動機護板 - (void)engineGuard; // 腳墊 - (void)mat; @end
(3)售後服務部門管理:售前服務(貼膜、裝配件、洗車、上牌等服務)和售後服務(維修、保養等)
#import@interface LHService : NSObject // 洗車服務 - (void)carWash; // 上牌服務 - (void)applyPlate; // 貼膜服務 - (void)filming; // 安裝行車記錄儀 - (void)installTachograph; @end
上面是我們的子系統接口,對於客戶來說沒必要關心這麼多業務,所以我們定義一個高層接口類來統一各個子系統的接口,這個類就是我們的4S銷售接待人員的角色類:LHService。
#import@interface LH4SWaiter : NSObject - (void)buyCarWithCash;// 現金買車 - (void)buyCarWithLoad;// 貸款買車 @end #import "LH4SWaiter.h" #import "LHFinance.h" #import "LHSales.h" #import "LHService.h" @interface LH4SWaiter () { LHFinance *finance;// 財務部門 LHSales *sales;// 銷售部門 LHService *service;// 售後服務部門 } @end @implementation LH4SWaiter - (instancetype)init { self = [super init]; if (self) { finance = [[LHFinance alloc] init]; sales = [[LHSales alloc] init]; service = [[LHService alloc] init]; } return self; } // 現金買車 - (void)buyCarWithCash{ // 現金支付 [finance cashPayment]; // 贈送禮品 [self gift]; // 提供服務 [self service]; } // 貸款買車 - (void)buyCarWithLoad{ BOOL _isSuccess = [finance applyLoan]; // 如果貸款審批下來,則提車、送贈品和服務 if (_isSuccess) { [sales provideCar]; [self gift]; [self service]; }else{ NSLog(@"貸款審批未通過!"); } } // 贈品 - (void)gift{ NSLog(@"贈品有:"); [sales carFilm]; [sales tachograph]; [sales engineGuard]; [sales mat]; } // 服務 - (void)service{ NSLog(@"售後服務:"); [service carWash]; [service applyPlate]; [service filming]; [service installTachograph]; } @end
這樣客戶只要告訴她我是現金支付還是貸款支付,剩余的事情她全部幫你做了,比如貸款的話,貸款的申請、審核、放款等。再比如哪些贈品,哪些服務她都幫你安排好。
客戶端只要簡單調用就可以了:
#import "ViewController.h" #import "LH4SWaiter.h" @interface ViewController () { LH4SWaiter *_waiter; } @end @implementation ViewController #pragma mark - #pragma mark System Method - (void)viewDidLoad { [super viewDidLoad]; _waiter = [[LH4SWaiter alloc] init]; } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; } #pragma mark - #pragma mark Button Event // 現金買車 - (IBAction)btnCashEvent:(UIButton *)sender { [_waiter buyCarWithCash]; } // 貸款買車 - (IBAction)btnLoanEvent:(UIButton *)sender { [_waiter buyCarWithLoad]; } @end
下面是輸出結果:
5.優點1.使用外觀模式可以使項目更好的分層,增強了代碼的擴展性。
2.客戶端屏蔽了子系統組件,使客戶端和子系統之間實現了松耦合關系。
源碼下載