什麼是設計模式,先來看段度孃的話:編程
設計模式(Design pattern)是一套被反覆使用、多數人知曉的、通過分類編目的、代碼設計經驗的總結。使用設計模式是爲了可重用代碼、讓代碼更容易被他人理解、保證代碼可靠性。 毫無疑問,設計模式於己於他人於系統都是多贏的;設計模式使代碼編制真正工程化;設計模式是軟件工程的基石脈絡,如同大廈的結構同樣。設計模式
其實咱們不須要這麼專業,在個人理解,設計模式就是一種規範化的編程習慣,養成了這樣的思想與習慣,對咱們的代碼,老是有好處了。框架
首先,工廠設計模式是建立對象的一種設計模式,一個嚴格意義上的工廠設計模式應該是一個純虛的構造方法。由子類進行具體對象的建立,咱們能夠這樣理解:如今有一個琿少牌製造工廠,這個工廠能夠製造多種交通工具,我大膽一些,假設它能夠製造飛機,輪船。小汽車,公交車,出租出和自行車,那麼,這些不一樣的車種雖然功能和大類別統一,可是他們的個體差別也是天地之別,就好比我飛機一小時能夠飛5000千米,自行車拼死了勁也不必定能騎20千米。因此,若是琿少這個大工廠要生產他們,也不可能把他們放在一塊兒生產。一個比較明智的決定是,開立分廠,好比琿少飛機工廠專門生產飛機,琿少自行車工廠專門生產自行車。函數
好了,若是將咱們這種人類世界的思惟運用於程序世界,那麼咱們能夠經過工廠的這種思惟方式來將一些大類抽象爲工廠,經過定義接口或者說是定義虛函數來規範這個大工廠的生產規模和流程,由其子類來具體實現這些方法,也就是由一個個小的分廠來明確的生產咱們須要的東西。這就是工廠設計模式的基本思路。工具
許多開發者或許並不在乎設計模式這個東西,咱們可能會想,我實現個人功能就能夠了,你管我怎麼設計呢。在這篇博客的開頭就說到,在我理解中,設計模式就是一種編程習慣和規範,更是一種衆多開發者摸索出來的經驗,這就像農業上的套種間種和你隨便種,哪種效率高,收成好,不言而喻。那麼在軟件設計中,工廠模式的應用在哪呢?atom
咱們先來體驗一下在iOS開發中,一些使用工廠設計模式的系統類爲咱們帶來的便捷之處:spa
在iOS的Foundation框架中,類簇是一種經常使用的設計模式,他將一些相近的,私有的,具體的子類組合在一個實體的抽象類下面,我稱這個抽象類爲實體的,是由於和咱們交互的接口承載者,就是這個抽象大類。咱們平時經常使用的三大類,NSString,NSArray,NSDictionary都是類簇,咱們經過他們建立的對象都是其子類對象的實例化,並非他自己的實例化,咱們還經過上面的例子來理解,我買了一輛琿少小汽車,這兩汽車的生產實際是在琿少汽車工廠生產的,可是我我的會依然認爲,這是琿少工廠出產的汽車。咱們能夠經過打印類名來驗證:設計
NSString * str = [[NSString alloc]initWithCString:"2" encoding:0]; NSLog(@"%@",[str class]);
結果以下:代理
能夠看到,真實的對象是NSString的子類__NSCFString進行實例化的。code
若是你經過NSString的事例仍是沒法體會到類簇,也就是工廠設計模式的優點,那麼下面這個例子你必定常常遇到:NSNumber。咱們在建立數字對象的時候,一般會這樣考慮,若是是int值,我須要一個IntNumber的類,float值,我須要一個FloatNumber類,若是foundation框架真這麼設計的話,那麼你如今就痛苦了,你不只要記住好多這樣類似的類,調用方法時也要相應的對象調其內的方法,這使開發者的開發變得更加繁瑣,而且對於開發者來講,我並不須要知道具體我建立了什麼類,我只是想讓他完成既定的方法。說的更通俗一點,仍是上面的製造工廠,使用者並不在意具體這個交通工具是哪一個地方生產出來的,只要它價錢和速度都是使用者預期的結果就行了。
經過上面的分析,咱們大體能夠總結出工廠這種設計模式的應用場景:
(1)當一個類並不知道要建立的具體對象是什麼,交由子類處理
(2)當一些類有類似的行爲和結構,只是具體實現不一樣時,能夠抽象出工廠
(3)使用者並不在意具體類型,只在意接口約定的行爲,而且這種行爲有個體差別
一樣是上面的例子,咱們來用代碼模擬一下:
首先,咱們建立一個抽象的工程類,在其中建立一些私有的子類:
#import <Foundation/Foundation.h> //交通工具的枚舉 typedef enum { car, boat, airport, bycicle, bus, taxi }ToolsName; //代理 @protocol TransPortationDelegate <NSObject> -(void)toHome:(Class)class; @end //抽象工廠類 @interface TramsPortationFactory : NSObject +(TramsPortationFactory*)buyTool:(ToolsName)tool; //共有的方法接口 -(int)shouldPayMoney; -(void)run; @property(nonatomic,strong)id<TransPortationDelegate>delegate; @end //具體實現的子類 @interface CarFactory : TramsPortationFactory @end @interface BoatFactory : TramsPortationFactory @end @interface AirportFactory : TramsPortationFactory @end @interface BycicleFactory : TramsPortationFactory @end @interface TaxiFactory : TramsPortationFactory @end @interface BusFactory : TramsPortationFactory @end
實現文件以下:
#import "TramsPortationFactory.h" @implementation TramsPortationFactory //實現的建立方法 +(TramsPortationFactory*)buyTool:(ToolsName)tool{ switch (tool) { case car: return [[CarFactory alloc]init]; break; case airport: return [[AirportFactory alloc]init]; break; case bycicle: return [[BycicleFactory alloc]init]; break; case boat: return [[BoatFactory alloc]init]; break; case taxi: return [[TaxiFactory alloc]init]; break; case bus: return [[BusFactory alloc]init]; break; default: break; } } -(int)shouldPayMoney{ return 0; } -(void)run{ [self.delegate toHome:[self class]]; } @end //各自類實現具體的行爲 @implementation CarFactory -(int)shouldPayMoney{ return 50; } -(void)run{ [super run]; NSLog(@"car to home"); } @end @implementation AirportFactory -(int)shouldPayMoney{ return 1000; } -(void)run{ [super run]; NSLog(@"fly to home"); } @end @implementation BoatFactory -(int)shouldPayMoney{ return 300; } -(void)run{ [super run]; NSLog(@"boat to home"); } @end @implementation BusFactory -(int)shouldPayMoney{ return 10; } -(void)run{ [super run]; NSLog(@"bus to home"); } @end @implementation BycicleFactory -(int)shouldPayMoney{ return 0; } -(void)run{ [super run]; NSLog(@"run to home"); } @end @implementation TaxiFactory -(int)shouldPayMoney{ return 100; } -(void)run{ [super run]; NSLog(@"go to home"); } @end
這樣,咱們的一個生產工廠就完成了,在外面,咱們只須要知道一個類,咱們的抽象父類,就能夠實現個子類的行爲,示例以下:
- (void)viewDidLoad { [super viewDidLoad]; TramsPortationFactory * tool = [TramsPortationFactory buyTool:car]; tool.delegate=self; [tool run]; NSLog(@"花了:%d錢",[tool shouldPayMoney]); TramsPortationFactory * tool2 = [TramsPortationFactory buyTool:airport]; tool2.delegate=self; [tool2 run]; NSLog(@"花了:%d錢",[tool2 shouldPayMoney]); } -(void)toHome:(Class)class{ NSLog(@"%@",NSStringFromClass(class)); }
能夠看到,對於開發者,咱們並不知曉CarFactory類的存在,咱們只須要經過TramsPortationFactory類,就可以操做各類交通工具,達到咱們的需求。
專一技術,熱愛生活,交流技術,也作朋友。
——琿少 QQ羣:203317592