工廠方法模式-(設(shè)計模式1)

什么是工廠方法模式?

要了解工廠方法模式先要了解其中的四種角色:

工廠抽象類G:抽象類,主要是定義生產(chǎn)產(chǎn)品類的接口。

工廠子類g:繼承工廠抽象類,實現(xiàn)工廠抽象類的接口,實例化相對應(yīng)的產(chǎn)品子類。

產(chǎn)品抽象類C:定義產(chǎn)品的基本屬性和方法。

產(chǎn)品子類:具體的產(chǎn)品類,工廠子類實例化的對象。

官方解釋工廠方法模式:定義一個用于創(chuàng)建對象的接口(工廠抽象類),讓子類(工廠子類)決定實例化哪些類(產(chǎn)品子類),使一個類(產(chǎn)品子類)的實例化延遲到子類(工廠子類)。

我的解釋:創(chuàng)建G(工廠抽象類),g(工廠子類),C(產(chǎn)品抽象類),c(產(chǎn)品子類)四個類,G定義一個生產(chǎn)產(chǎn)品的接口如createProduct,g繼承G,g實現(xiàn)createProduct,創(chuàng)建c并將c返回,c繼承C。這樣項目如果要修改c時只需要修改g中createProduct方法中實例化的對象。

工廠方法模式的優(yōu)缺點:

優(yōu)點:

1.將實例化產(chǎn)品類全部歸到一個接口,當(dāng)要換產(chǎn)品類時,只需要修改接口中實例化的類就行了,而項目中的其他地方不用變換。

2.刪除和增加是變得容易,符合開放封閉原則

缺點:

1.如要要增加產(chǎn)品類時,也要對應(yīng)的增加工廠類。

工廠方法模式的代碼實現(xiàn):

1.創(chuàng)建一個形狀基類PFAbstractShape。該類中定義了形狀的基本行為和屬性,如下代碼所示:

PFAbstractShape.h

#import <Foundation/Foundation.h>

#define PF_Exception_Format @"在%@的子類中必須override:%@方法"

@interfacePFAbstractShape :NSObject

@property(nonatomic,weak)NSString*name;

//子類必須重寫這個draw方法,否則會拋出異常錯誤

-(void)draw;

@end

PFAbstractShape.m

#import"PFAbstractShape.h"

@implementationPFAbstractShape

-(void)draw

{

//如果是通過PFAbstractShape的實例調(diào)用此處的draw,則繪制一個PFAbstractShape圖形

if([selfisMemberOfClass:[PFAbstractShapeclass]]) {

NSLog(@"繪制一個PFAbstractShape圖形");

}else{

//如果是通過PFAbstractShape子類的實例調(diào)用了此處的draw,則拋出一個異常:表明子類并沒有重寫draw方法。

//注:在OC中并沒有abstract class的概念,只有protocol,如果在基類中只定義接口(沒有具體方法的實現(xiàn)),

//則可以使用protocol,這樣會更方便。

[NSExceptionraise:NSInternalInconsistencyException

format:PF_Exception_Format, [NSStringstringWithUTF8String:object_getClassName(self)],NSStringFromSelector(_cmd)];

}

}

在上面的代碼中定義了一個draw方法,為了讓子類必須實現(xiàn)該方法,在PFAbstractShape中做了特殊處理,具體內(nèi)容可以看上面的代碼,已經(jīng)有注視了。

2.子類化形狀基類。首先子類化一個圓形類:PFCircleShape。

PFCircleShape.h

#import"PFAbstractShape.h"

@interfacePFCircleShape :PFAbstractShape

@end

PFCircleShape.m

#import"PFCircleShape.h"

@implementationPFCircleShape

- (void)draw

{

NSLog(@"繪制一個PFCircleShape圖形");

}

@end

在上面的子類中,重寫了基類的draw方法。同樣,我們再子類化一個正方形類,并重寫draw方法,如下代碼所示:

PFSquareShape.h

#import"PFAbstractShape.h"

@interfacePFSquareShape :PFAbstractShape

@end

PFSquareShape.m

#import"PFSquareShape.h"

@implementationPFSquareShape

- (void)draw

{

NSLog(@"繪制一個PFSquareShape圖形");

}

@end

3.創(chuàng)建一個工廠方法的基類PFAbstractFactory

PFAbstractFactory.h

#import<Foundation/Foundation.h>

#import"PFAbstractShape.h"

@interfacePFAbstractFactory :NSObject

- (PFAbstractShape*)factoryMethod;

@end

PFAbstractFactory.m

#import"PFAbstractFactory.h"

@implementationPFAbstractFactory

-(PFAbstractShape*)factoryMethod

{

//在此處,子類必須重寫factoryMethod方法。當(dāng)然,在工廠模式中,也可以在此處返回一個默認(rèn)的Product。

//如果是通過PFAbstractFactory子類的實例調(diào)用了此處的factoryMethod,則拋出一個異常:表明子類并沒有重寫factoryMethod方法。

[NSExceptionraise:NSInternalInconsistencyException

format:PF_Exception_Format, [NSStringstringWithUTF8String:object_getClassName(self)],NSStringFromSelector(_cmd)];

//下面這個return語句只是為了消除警告,實際上永遠(yuǎn)都不會執(zhí)行到這里。

returnnil;

}

@end

在上面的代碼中,定義了一個factoryMethod,該類的子類必須實現(xiàn)該方法,通過實現(xiàn)該方法,返回一個具體的形狀對象。下面來看看該類的子類化。

4.子類化工廠方法的基類。首先子類化一個圓形工廠方法PFCircleShapeFactory:

PFCircleShapeFactory.h

#import"PFAbstractFactory.h"

#import"PFCircleShape.h"

@interfacePFCircleShapeFactory :PFAbstractFactory

@end

PFCircleShapeFactory.m

#import"PFCircleShapeFactory.h"

@implementationPFCircleShapeFactory

- (PFAbstractShape*)factoryMethod

{

return[[PFCircleShapealloc]init];

}

@end

如上代碼所示,重寫了factoryMethod,返回一個PFCircleShape實例。下面來看看另外一個子類PFSquareShapeFactory

PFSquareShapeFactory.h

#import"PFAbstractFactory.h"

#import"PFSquareShape.h"

@interfacePFSquareShapeFactory :PFAbstractFactory

@end

PFSquareShapeFactory.m

#import"PFSquareShapeFactory.h"

@implementationPFSquareShapeFactory

- (PFAbstractShape*)factoryMethod{

return[[PFSquareShapealloc]init];

}

@end

該子類返回的是一個PFSquareShape實例。

5.工廠方法的使用。定義一個PFClient類,在該類中演示工廠方法的使用。代碼如下:

PFClient.h

#import

@interfacePFClient :NSObject

- (void)doSomething;

@end

PFClient.m

#import"PFClient.h"

#import"PFAbstractFactory.h"

#import"PFCircleShapeFactory.h"

#import"PFSquareShapeFactory.h"

#import"PFAbstractShape.h"

#import"PFCircleShape.h"

#import"PFSquareShape.h"

@implementationPFClient

-(void)doSomething

{

//用到多態(tài),父指針指向子對象,當(dāng)要修改實例化的對象時,只需要修改工廠里的實例化對象

//工廠方法的實例化

PFAbstractFactory*circleShapefactory = [[PFCircleShapeFactoryalloc]init];

PFAbstractFactory*squareShapefactory = [[PFSquareShapeFactoryalloc]init];

//通過工廠方法實例化對應(yīng)的形狀

PFAbstractShape*circleShape = [circleShapefactoryfactoryMethod];

PFAbstractShape*squareShape = [squareShapefactoryfactoryMethod];

//調(diào)用形狀的方法

[circleShapedraw];

[squareShapedraw];

}

@end

如上代碼所示,首先實例化兩個工廠方法,并通過工廠方法創(chuàng)建出對應(yīng)的形狀,最后調(diào)用形狀的draw方法進(jìn)行測試。會在控制臺窗口輸出如下內(nèi)容:

2013-05-16 10:12:46.292 FactoryMethodPattern[2845:c07] 繪制一個PFCircleShape圖形

2013-05-16 10:12:46.295 FactoryMethodPattern[2845:c07] 繪制一個PFSquareShape圖形

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,554評論 19 139
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法,類相關(guān)的語法,內(nèi)部類的語法,繼承相關(guān)的語法,異常的語法,線程的語...
    子非魚_t_閱讀 34,692評論 18 399
  • 簡單工廠模式雖然簡單,但存在一個很嚴(yán)重的問題。當(dāng)系統(tǒng)中需要引入新產(chǎn)品時,由于靜態(tài)工廠方法通過所傳入?yún)?shù)的不同來創(chuàng)建...
    justCode_閱讀 1,307評論 1 9
  • 設(shè)計原則: 要依賴抽象,不要依賴具體類 目錄 本文的結(jié)構(gòu)如下: 什么是工廠方法模式 為什么要用該模式 模式的結(jié)構(gòu) ...
    w1992wishes閱讀 1,429評論 0 6
  • 《歡樂頌》中安迪聰明睿智的職場形象,很多人都喜歡。安迪,哥倫比亞大學(xué)商學(xué)院畢業(yè),華爾街投行高管,回國后在上海朋友的...
    辰辰_Amy閱讀 1,403評論 4 50

友情鏈接更多精彩內(nèi)容