開篇
在這篇文章中我們講下工廠方法和抽象工廠這兩種設(shè)計(jì)模式瓶堕。幾乎在每個(gè)面向?qū)ο蟮某绦蚶锒紩?huì)看到工廠方法败砂,隨便讓一個(gè)程序員或者軟院,計(jì)科的學(xué)生說個(gè)設(shè)計(jì)模式都會(huì)說出工廠模式世落』刺冢看似普通的東西其實(shí)并不普通,今天我們就來認(rèn)真的研究下什么是工廠方法屉佳,它和抽象工廠有什么異同谷朝?抽絲剝繭,總結(jié)一套心得武花,在以后寫程序的時(shí)候更得心應(yīng)手圆凰,不會(huì)心存疑慮。
工廠方法
總的來說体箕,工廠方法是抽象工廠的組成部分专钉,各種具體工廠類重載抽象工廠類中的方法挑童,并用這些工廠方法創(chuàng)建具體產(chǎn)品。工廠方法的精髓在于: 一個(gè)類無法預(yù)期要生成那個(gè)類的對(duì)象跃须,需要其子類來指定要生成的對(duì)象炮沐。
下圖是工廠方法模式的靜態(tài)類圖(圖片來源于《編程之道》)
Creator是一個(gè)抽象的工廠父類,定義了FactoryMethod這個(gè)需要重載的工廠方法回怜,其子類ConcreteCreator實(shí)現(xiàn)了這個(gè)方法大年,返回具體的產(chǎn)品。在1994年Wesley最初定義工廠模式的時(shí)候玉雾,他說: 工廠方法模式翔试,就是讓子類決定實(shí)例化哪個(gè)類,使得一個(gè)類的實(shí)例化延遲到其子類复旬。在平時(shí)的coding中垦缅,我們也會(huì)經(jīng)常遇到這樣的情況,例如你從網(wǎng)絡(luò)請(qǐng)求一些產(chǎn)品的列表驹碍,但是產(chǎn)品種類很多壁涎,需要運(yùn)行時(shí)才能確定,這時(shí)候就需要使用工廠方法志秃,例如[[self class] xxxFactory]來讓具體子類生成產(chǎn)品怔球。
何時(shí)使用工廠方法以及它的好處
以下情形會(huì)讓你自然而然的想到使用工廠方法:
- 編譯時(shí)無法確定要?jiǎng)?chuàng)建對(duì)象的類
- 想讓子類決定運(yùn)行時(shí)創(chuàng)建什么
- 局部化信息。例如一個(gè)類有若干子類為其輔助類浮还,而你想返回具體的子類的信息
工廠方法可以讓創(chuàng)建出來的產(chǎn)品有一組共同的行為竟坛,而且客戶端無需修改任何代碼就可以擁有不同的產(chǎn)品,當(dāng)你想加入新產(chǎn)品的時(shí)候钧舌,只需增加一個(gè)子類担汤,無需修改客戶端代碼。
Demo
我們現(xiàn)在要生成兩種畫布洼冻,一個(gè)是ClothCanvasView(布質(zhì)風(fēng)格)另一個(gè)是PaperCanvasView(紙質(zhì)風(fēng)格)崭歧。我們將創(chuàng)建一個(gè)抽象的generator來生成這些畫布。
如上圖撞牢,CanvasViewGenerator是一個(gè)基類率碾,包含一個(gè)工廠方法canvasViewWithFrame,其兩個(gè)子類負(fù)責(zé)實(shí)現(xiàn)和返回具體的CanvasView.
CanvasViewGenerator的代碼:
#import "CanvasViewGenerator.h"
@implementation CanvasViewGenerator
- (void)canvasViewWithFrame:(CGRect)aFrame
{
return [[CanvasView alloc] initWithFrame:aFrame];
}
這里面只是返回?zé)o圖案的CanvasView普泡,具體的view需要子類來返回播掷。
PaperCanvasViewGenerator的代碼:
#import "PaperCanvasViewGenerator.h"
@implementation PaperCanvasViewGenerator
- (void)canvasViewWithFrame:(CGRect)aFrame
{
return [[PaperCanvasView alloc] initWithFrame:aFrame];
}
ClothCanvasViewGenerator的代碼:
#import "ClothCanvasViewGenerator.h"
@implementation ClothCanvasViewGenerator
- (void)canvasViewWithFrame:(CGRect)aFrame
{
return [[ClothCanvasView alloc] initWithFrame:aFrame];
}
當(dāng)使用畫布的時(shí)候审编,只需在CanvasViewController里面調(diào)用 [generator canvasViewWithFrame:aFrame]即可撼班,generator類型是基類類型。
工廠方法就是這些了垒酬,它的應(yīng)用非常普遍砰嘁,很好地封裝了工廠子類件炉,并與客戶端類解耦。下一篇介紹抽象工廠矮湘,以及和工廠方法的對(duì)比斟冕。