第4章 工廠方法 -第二部分 對(duì)象創(chuàng)建

生產(chǎn)者自身不必是抽象工廠网棍,它可以是任何類。

要點(diǎn)在于
1.不是直接創(chuàng)建對(duì)象妇智,
2.而是使用類或?qū)ο蟮墓S方法創(chuàng)建具體產(chǎn)品滥玷,
3.并以抽象類型返回氏身。

工廠方法模式是抽象工廠模式的組成部分。各種具體工廠重載其抽象工廠父類中定義的工廠方法惑畴,并用這個(gè)重載的工廠方法創(chuàng)建自己的產(chǎn)品(對(duì)象)蛋欣。

4.1 何為工廠方法模式

工廠方法也稱為虛構(gòu)造器(virtual constructor)。
他適用于這種情況:一個(gè)類無法預(yù)期需要生成哪個(gè)類的對(duì)象桨菜,想讓其子類來指定所生成的對(duì)象豁状。

工廠方法模式的靜態(tài)類結(jié)構(gòu)如圖4-1所示。

工廠方法模式的類圖
說明:
1. 抽象的Product(產(chǎn)品)定義了工廠方法創(chuàng)建的對(duì)象的接口倒得。
2. ConcreteProduct實(shí)現(xiàn)了Product接口。
3. Creator定義了返回Product對(duì)象的工廠方法夭禽。它也可以為工廠方法定義一個(gè)默認(rèn)實(shí)現(xiàn)霞掺,返回默認(rèn)ConcreteProduct對(duì)象。Creator的其他操作可以調(diào)用此工廠方法創(chuàng)建Product對(duì)象讹躯。
4. ConcreateCreator是Creator的子類菩彬。它重載了工廠方法,以返回ConcreteProduct的實(shí)例潮梯。

工廠方法模式:定義創(chuàng)建對(duì)象的接口骗灶,讓子類決定實(shí)例化哪一個(gè)類。工廠方法使得一個(gè)類的實(shí)例化延遲到其子類秉馏。

工廠方法
1.通過類繼承創(chuàng)建抽象產(chǎn)品耙旦。
2.創(chuàng)建一種產(chǎn)品。
3.子類化創(chuàng)建者并重載工廠方法以創(chuàng)建新產(chǎn)品萝究。

4.2 何時(shí)使用工廠方法

  • 編譯時(shí)無法準(zhǔn)確預(yù)期要?jiǎng)?chuàng)建的對(duì)象的類免都;
  • 類想讓其子類決定在運(yùn)行時(shí)創(chuàng)建什么;
  • 類由若干輔助類為其子類帆竹,而你想將返回哪個(gè)字累這一信息局部化绕娘。
    使用這一模式的最低限度是:工廠方法能給予類在變更返回哪一種對(duì)象這一點(diǎn)上更多的靈活性。

4.3 為何這是創(chuàng)建對(duì)象的安全方法

工廠方法模式讓客戶程序可以要求由工廠方法創(chuàng)建的對(duì)象擁有一組共同的行為栽连。所以往類層次結(jié)構(gòu)中引入新的具體產(chǎn)品并不需要修改客戶端代碼险领,因?yàn)榉祷氐娜魏尉唧w對(duì)象的接口都跟客戶端一直在用的從前的接口相同。

4.4 在TouchPainter中生成不同畫布

4.1 畫布類

CanvasView:畫布類

//CanvasView.h
@interface CanvasView : UIView

@end
//CanvasView.m
@implementation CanvasView

@end

ClothCanvasView:有布質(zhì)風(fēng)格的背景

//ClothCanvasView.h
#import "CanvasView.h"

@interface ClothCanvasView : CanvasView
{
    // 一些私有變量
}

// 其他一些特定行為
@end
//ClothCanvasView.m
@implementation ClothCanvasView

-(instancetype)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        // 在上面添加一個(gè)紙圖像視圖作為畫布背景
        UIImage *backgroundImage = [UIImage imageNamed:@"cloth"];
        UIImageView *backgroundView = [[UIImageView alloc] initWithImage:backgroundImage];
        [self addSubview:backgroundView];
    }
    return self;
}

// 其他行為的實(shí)現(xiàn)

@end

PaperCanvasView:有再生紙風(fēng)格的背景

//.h
#import "CanvasView.h"

@interface PaperCanvasView : CanvasView
{
    // 一些私有變量
}
// 其他一些特定行為
@end
//PaperCanvasView.m
@implementation PaperCanvasView

-(instancetype)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        // 在上面添加一個(gè)紙圖像視圖作為畫布背景
        UIImage *backgroundImage = [UIImage imageNamed:@"paper"];
        UIImageView *backgroundView = [[UIImageView alloc] initWithImage:backgroundImage];
        [self addSubview:backgroundView];
    }
    return self;
}

// 其他行為的實(shí)現(xiàn)


@end
4.2 生成器類

為定義好的產(chǎn)品各自定義一個(gè)生成器秒紧。
CanvasViewGenerator:默認(rèn)畫布的生成器

//CanvasViewGenerator.h
#import "CanvasView.h"

@interface CanvasViewGenerator : NSObject
{
    
}

- (CanvasView *)canvasViewWithFrame:(CGRect)aFrame;

@end
//CanvasViewGenerator.m
@implementation CanvasViewGenerator
-(CanvasView *)canvasViewWithFrame:(CGRect)aFrame
{
    return [[CanvasView alloc] initWithFrame:aFrame];
}
@end

PaperCanvasViewGenerator:紙風(fēng)格畫布的生成器

//PaperCanvasViewGenerator.h
#import "PaperCanvasView.h"

@interface PaperCanvasViewGenerator : CanvasViewGenerator
{
    
}

-(CanvasView *)canvasViewWithFrame:(CGRect)aFrame;

@end
//PaperCanvasViewGenerator.m
@implementation PaperCanvasViewGenerator

-(CanvasView *)canvasViewWithFrame:(CGRect)aFrame
{
    return [[PaperCanvasView alloc] initWithFrame:aFrame];
}

@end

ClothCanvasViewGenerator:布風(fēng)格畫布的生成器

//ClothCanvasViewGenerator.h
#import "CanvasViewGenerator.h"

@interface ClothCanvasViewGenerator : CanvasViewGenerator
{
    
}
-(CanvasView *)canvasViewWithFrame:(CGRect)aFrame;

@end
//ClothCanvasViewGenerator.m
#import "ClothCanvasView.h"

@implementation ClothCanvasViewGenerator

-(CanvasView *)canvasViewWithFrame:(CGRect)aFrame{
    return [[ClothCanvasView alloc] initWithFrame:aFrame];
}

@end
4.3 CanvasViewController
//CanvasViewController.h
#import "CanvasView.h"
#import "CanvasViewGenerator.h"

@interface CanvasViewController : UIViewController
{
    @private
    CanvasView *_canvasView; //畫布視圖
}
@property (nonatomic, strong) CanvasView *canvasView;

- (void)loadCanvasViewWithGenerator:(CanvasViewGenerator *)generator;

@end
//CanvasViewController.m
// 實(shí)現(xiàn)viewDidLoad绢陌,進(jìn)行視圖加載后的追加設(shè)置。
// 通常視圖是從nib加載噩茄。
- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    
    // 使用CanvasViewGenerator的工程方法取得默認(rèn)畫布視圖
    CanvasViewGenerator *defaultGenerator = [[CanvasViewGenerator alloc] init];
    [self loadCanvasViewWithGenerator:defaultGenerator];
}
// 限于篇幅下面,略去了無關(guān)的方法

#pragma mark Loading a CanvasView from a CanvasViewGenerator
-(void)loadCanvasViewWithGenerator:(CanvasViewGenerator *)generator
{
    [_canvasView removeFromSuperview];
    CGRect aFrame = CGRectMake(0, 0, 320, 436);
    CanvasView *aCanvasView = [generator canvasViewWithFrame:aFrame];
    [self setCanvasView:aCanvasView];
    [self.view addSubview:_canvasView];
}

應(yīng)用程序通過把具體生成器的實(shí)例傳給-(void)loadCanvasViewWithGenerator:(CanvasViewGenerator *)generator方法,來生成具體的畫布绩聘。

4.5 在Cocoa Touch框架中應(yīng)用工廠方法

例:NSNumber numberWith*方法
[NSNumber numberWithBool:bool];
[NSNumber numberWithChar:char];

4.6 總結(jié)

   工廠方法從代碼中消除了對(duì)應(yīng)用程序特有類的耦合沥割。
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末耗啦,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子机杜,更是在濱河造成了極大的恐慌帜讲,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,104評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件椒拗,死亡現(xiàn)場(chǎng)離奇詭異似将,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)蚀苛,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,816評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門在验,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人堵未,你說我怎么就攤上這事腋舌。” “怎么了渗蟹?”我有些...
    開封第一講書人閱讀 168,697評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵块饺,是天一觀的道長。 經(jīng)常有香客問我雌芽,道長授艰,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,836評(píng)論 1 298
  • 正文 為了忘掉前任世落,我火速辦了婚禮淮腾,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘岛心。我一直安慰自己来破,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,851評(píng)論 6 397
  • 文/花漫 我一把揭開白布忘古。 她就那樣靜靜地躺著徘禁,像睡著了一般。 火紅的嫁衣襯著肌膚如雪髓堪。 梳的紋絲不亂的頭發(fā)上送朱,一...
    開封第一講書人閱讀 52,441評(píng)論 1 310
  • 那天,我揣著相機(jī)與錄音干旁,去河邊找鬼驶沼。 笑死,一個(gè)胖子當(dāng)著我的面吹牛争群,可吹牛的內(nèi)容都是我干的回怜。 我是一名探鬼主播,決...
    沈念sama閱讀 40,992評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼换薄,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼玉雾!你這毒婦竟也來了翔试?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,899評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤复旬,失蹤者是張志新(化名)和其女友劉穎垦缅,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體驹碍,經(jīng)...
    沈念sama閱讀 46,457評(píng)論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡壁涎,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,529評(píng)論 3 341
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了志秃。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片怔球。...
    茶點(diǎn)故事閱讀 40,664評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖洽损,靈堂內(nèi)的尸體忽然破棺而出庞溜,到底是詐尸還是另有隱情,我是刑警寧澤碑定,帶...
    沈念sama閱讀 36,346評(píng)論 5 350
  • 正文 年R本政府宣布,位于F島的核電站又官,受9級(jí)特大地震影響延刘,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜六敬,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,025評(píng)論 3 334
  • 文/蒙蒙 一碘赖、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧外构,春花似錦普泡、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,511評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至垒酬,卻和暖如春砰嘁,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背勘究。 一陣腳步聲響...
    開封第一講書人閱讀 33,611評(píng)論 1 272
  • 我被黑心中介騙來泰國打工矮湘, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人口糕。 一個(gè)月前我還...
    沈念sama閱讀 49,081評(píng)論 3 377
  • 正文 我出身青樓缅阳,卻偏偏與公主長得像,于是被迫代替她去往敵國和親景描。 傳聞我的和親對(duì)象是個(gè)殘疾皇子十办,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,675評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容

  • 1.ios高性能編程 (1).內(nèi)層 最小的內(nèi)層平均值和峰值(2).耗電量 高效的算法和數(shù)據(jù)結(jié)構(gòu)(3).初始化時(shí)...
    歐辰_OSR閱讀 29,417評(píng)論 8 265
  • Swift1> Swift和OC的區(qū)別1.1> Swift沒有地址/指針的概念1.2> 泛型1.3> 類型嚴(yán)謹(jǐn) 對(duì)...
    cosWriter閱讀 11,113評(píng)論 1 32
  • 1 場(chǎng)景問題# 1.1 繼續(xù)導(dǎo)出數(shù)據(jù)的應(yīng)用框架## 在討論工廠方法模式的時(shí)候秀撇,提到了一個(gè)導(dǎo)出數(shù)據(jù)的應(yīng)用框架。 對(duì)于...
    七寸知架構(gòu)閱讀 5,760評(píng)論 1 64
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理橘洞,服務(wù)發(fā)現(xiàn)捌袜,斷路器,智...
    卡卡羅2017閱讀 134,707評(píng)論 18 139
  • 你的杳無音信五天了炸枣,伸出手來虏等,看不出五指,卻能感受到我們五指交叉适肠,黑夜讓我浮想聯(lián)翩霍衫。漆黑的眼膜,卻不能透過黑夜籠罩...
    沐府墓主閱讀 173評(píng)論 0 0