設(shè)計模式一(工廠模式)

工廠模式可以簡單概括為同類型不同型號的產(chǎn)品有各自對應(yīng)的工廠進行生產(chǎn)畸颅。
比如iPhone手機旗下有iPhoneX及iPhone8兩種型號的手機,iPhoneX有自己iPhoneX的專屬工廠進行生產(chǎn)逮栅,而iPhone8有自己iPhone8的專屬工廠進行生產(chǎn)。兩條生產(chǎn)線沒有交集互不影響驹闰,后期如果新增或廢棄相關(guān)類型的產(chǎn)品也不會影響到原有的生產(chǎn)線晨雳。

三種模式

  • 簡單工廠模式:簡單工廠模式是由一個工廠對象決定創(chuàng)建出哪一種產(chǎn)品類的實例。簡單工廠模式是工廠模式家族中最簡單實用的模式紧卒,可以理解為是不同工廠模式的一個特殊實現(xiàn)侥衬。

  • 工廠模式:抽象了工廠接口的具體產(chǎn)品,應(yīng)用程序的調(diào)用不同工廠創(chuàng)建不同產(chǎn)品對象跑芳。(抽象產(chǎn)品)

  • 抽象工廠模式:在工廠模式的基礎(chǔ)上抽象了工廠轴总,應(yīng)用程序調(diào)用抽象的工廠發(fā)發(fā)創(chuàng)建不同產(chǎn)品對象。(抽象產(chǎn)品+抽象工廠)

一博个、簡單工廠模式

1怀樟、簡單工廠模式定義

? 簡單工廠模式(Simple Factory Pattern):定義一個工廠類,它可以根據(jù)參數(shù)的不同返回不同類的實例盆佣,被創(chuàng)建的實例通常都具有共同的父類往堡。因為在簡單工廠模式中用于創(chuàng)建實例的方法是靜態(tài)(static)方法,因此簡單工廠模式又被稱為靜態(tài)工廠方法(Static Factory Method)模式共耍,它屬于類創(chuàng)建型模式虑灰。

? 注意:簡單工廠模式并不屬于GoF 23個經(jīng)典設(shè)計模式,但通常將它作為學(xué)習(xí)其他工廠模式的基礎(chǔ)痹兜。

簡單工廠模式的要點:當(dāng)你需要什么瘩缆,只需要傳入一個正確的參數(shù),就可以獲取你所需要的對象佃蚜,而無須知道其創(chuàng)建細節(jié)。

2着绊、簡單工廠模式包含的角色
  • Factory(工廠角色):工廠角色即工廠類谐算,它是簡單工廠模式的核心,負責(zé)實現(xiàn)創(chuàng)建所有產(chǎn)品實例的內(nèi)部邏輯归露;工廠類可以被外界直接調(diào)用洲脂,創(chuàng)建所需的產(chǎn)品對象;在工廠類中提供了靜態(tài)的工廠方法factoryMethod(),它的返回類型為抽象產(chǎn)品類型Product恐锦。

  • Product(抽象產(chǎn)品角色):它是工廠類所創(chuàng)建的所有對象的父類往果,封裝了各種產(chǎn)品對象的公有方法,它的引入將提高系統(tǒng)的靈活性一铅,使得在工廠類中只需定義一個通用的工廠方法陕贮,因為所有創(chuàng)建的具體產(chǎn)品對象都是其子類對象。

  • ConcreteProduct(具體產(chǎn)品角色):它是簡單工廠模式的創(chuàng)建目標(biāo)潘飘,所有被創(chuàng)建的對象都充當(dāng)這個角色的某個具體類的實例肮之。每一個具體產(chǎn)品角色都繼承了抽象產(chǎn)品角色,需要實現(xiàn)在抽象產(chǎn)品中聲明的抽象方法卜录。

? 簡單工廠模式的要點:當(dāng)你需要什么戈擒,只需要傳入一個正確的參數(shù),就可以獲取你所需要的對象艰毒,而無須知道其創(chuàng)建細節(jié)筐高。

3、結(jié)構(gòu)圖
簡單工廠模式

父類Fruits具有一個屬性name和一個方法sweet丑瞧、poorTaste柑土,AppleFruit和OrangeFruit繼承自Fruits,簡單工廠類為FruitFactory嗦篱,負責(zé)根據(jù)傳入的不同參數(shù)FruitType來決定生產(chǎn)的是AppleFruit還是OrangeFruit冰单。

4、示例

本Demo還是以小販賣蘋果和橘子為例:(小販就是一個工廠灸促,他為你提供蘋果诫欠,橘子等水果)

  • 先創(chuàng)建Fruits水果類,有一個sweet()浴栽、poorTaste()抽象方法荒叼,表示抽象產(chǎn)品類;
  • 然后創(chuàng)建AppleFruit和OrangeFruit類典鸡,繼承自Fruits類被廓,表示具體產(chǎn)品類;
  • 然后創(chuàng)建FruitFactory工廠類萝玷,有一個fruitsFactory:type方法嫁乘,聲明但未實現(xiàn),表示抽象工廠球碉;

具體代碼如下:
Fruits類:

#import <Foundation/Foundation.h>  //Fruits.h

@interface Fruits : NSObject
/**水果名*/
@property (nonatomic,copy) NSString *name;
- (void)sweet; /**< 甜 */
- (void)poorTaste; /**< 不好吃 */
@end


#import "Fruits.h"     //Fruits.m

@implementation Fruits
// 甜
- (void)sweet {}

// 不好吃
- (void)poorTaste {}
@end

AppleFruit和OrangeFruit類

/*------------------AppleFruit------------------*/
#import "Fruits.h"    //AppleFruit.h

//遵循了開閉原則
@interface AppleFruit : Fruits
- (void)freshApple; /**< 新鮮的蘋果 */   // 開閉原則
@end



#import "AppleFruit.h"       //AppleFruit.m

@implementation AppleFruit
@synthesize name;
// 甜
- (void)sweet {
    NSLog(@"%@非常甜的啦-----%s",self.name, __func__);
}

// 不好吃
- (void)poorTaste {
    NSLog(@"%@不好吃的啦-----%s",self.name,__func__);
}

// 新鮮的蘋果
- (void)freshApple {
     NSLog(@"%@是新鮮的-----%s",self.name,__func__);
}
@end


/*------------------OrangeFruit------------------*/
#import "Fruits.h"                       //OrangeFruit.h

@interface OrangeFruit : Fruits

- (void)acidOrange; /**< 酸橘子 */
@end



#import "OrangeFruit.h"           //OrangeFruit.m

@implementation OrangeFruit
@synthesize name;
// 甜
- (void)sweet {
   NSLog(@"%@非常甜的啦-----%s",self.name, __func__);
}

// 不好吃
- (void)poorTaste {
    NSLog(@"%@不好的啦-----%s",self.name, __func__);
}

/**< 酸橘子 */
- (void)acidOrange {
    NSLog(@"%@有點酸-----%s",self.name, __func__);
}
@end

FruitFactory類:

#import <Foundation/Foundation.h>             //FruitFactory.h
#import "Fruits.h"
#import "AppleFruit.h"
#import "OrangeFruit.h"

typedef NS_ENUM(NSInteger,FruitType){
    FruitTypeApple,
    FruitTypeOrange,
};

@interface FruitFactory : NSObject
// 創(chuàng)造水果的工廠
+ (Fruits *)fruitsFactory:(FruitType)type;
@end



#import "FruitFactory.h"                         //FruitFactory.m
@implementation FruitFactory
+ (Fruits *)fruitsFactory:(FruitType)type {
    // 創(chuàng)建空的對象.在工廠方法里面進行水果的制造
    Fruits *fruits = nil;

    switch (type) {
        case FruitTypeApple:
            fruits = [[AppleFruit alloc] init];
            break;

        case FruitTypeOrange:
            fruits = [[OrangeFruit alloc] init];
            break;

        default:
            break;
    }
    return fruits;
}
@end

運行代碼:

#import "ViewController.h"
#import "FruitFactory.h"
@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
   
/*###############SimpleFactoryPattern(簡單工廠模式)######################*/
    // 在水果工廠里面創(chuàng)建出蘋果
    Fruits *fruit =  [FruitFactory fruitsFactory:FruitTypeApple];
    fruit.name = @"蘋果";
    [fruit sweet];
    
    // 在水果工廠里面創(chuàng)建出蘋果
    Fruits *fruit1 =  [FruitFactory fruitsFactory:FruitTypeOrange];
    fruit1.name = @"橘子";
    [fruit1 poorTaste];
    
    // 在水果工廠里面創(chuàng)建出蘋果, 調(diào)用私有的方法
    AppleFruit *apple =  (AppleFruit*)[FruitFactory fruitsFactory:FruitTypeApple];
    apple.name = @"蘋果";
    [apple freshApple];
    
    // 在水果工廠里面創(chuàng)建出橘子, 調(diào)用私有的方法
    OrangeFruit *orage =  (OrangeFruit *)[FruitFactory fruitsFactory:FruitTypeOrange];
    orage.name = @"橘子";
    [orage acidOrange];
}
@end

打印結(jié)果:

2019-12-10 16:07:55.643264+0800 設(shè)計模式[78854:2676436] 蘋果非常甜的啦------[AppleFruit sweet]
2019-12-10 16:07:55.643415+0800 設(shè)計模式[78854:2676436] 橘子不好的啦------[OrangeFruit poorTaste]
2019-12-10 16:07:55.643524+0800 設(shè)計模式[78854:2676436] 蘋果是新鮮的------[AppleFruit freshApple]
2019-12-10 16:07:55.643629+0800 設(shè)計模式[78854:2676436] 橘子有點酸------[OrangeFruit acidOrange]
5蜓斧、總結(jié)

簡單工廠模式的簡化:有時候,為了簡化簡單工廠模式睁冬,我們可以將抽象產(chǎn)品類和工廠類合并挎春,將靜態(tài)工廠方法移至抽象產(chǎn)品類中。比如在Fruits類中添加一個方法:

Fruits類:

#import <Foundation/Foundation.h>

typedef NS_ENUM(NSInteger,FruitType){
    FruitTypeApple,
    FruitTypeOrange,
};

@interface Fruits : NSObject
/**水果名*/
@property (nonatomic,copy) NSString *name;
- (void)sweet; /**< 甜 */
- (void)poorTaste; /**< 不好吃 */

// 創(chuàng)造水果的工廠
+ (Fruits *)fruitsFactory:(FruitType)type;
@end


#import "Fruits.h"
#import "AppleFruit.h"
#import "OrangeFruit.h"
@implementation Fruits
// 甜
- (void)sweet {}

// 不好吃
- (void)poorTaste {}

+ (Fruits *)fruitsFactory:(FruitType)type {
    // 創(chuàng)建空的對象.在工廠方法里面進行水果的制造
    Fruits *fruits = nil;

    switch (type) {
        case FruitTypeApple:
            fruits = [[AppleFruit alloc]init];
            break;

        case FruitTypeOrange:
            fruits = [[OrangeFruit alloc]init];
            break;

        default:
            break;
    }
    return fruits;
}
@end

運行代碼:

Fruits *fruit =  [Fruits fruitsFactory:FruitTypeApple];
fruit.name = @"蘋果";
[fruit sweet];
    
AppleFruit *apple =  (AppleFruit*)[Fruits fruitsFactory:FruitTypeApple];
apple.name = @"蘋果";
[apple freshApple];

? 簡單工廠模式提供了專門的工廠類用于創(chuàng)建對象,將對象的創(chuàng)建和對象的使用分離開直奋,它作為一種最簡單的工廠模式在軟件開發(fā)中得到了較為廣泛的應(yīng)用能庆。

1)優(yōu)點
  • 工廠類包含必要的判斷邏輯,可以決定在什么時候創(chuàng)建哪一個產(chǎn)品類的實例脚线,客戶端可以免除直接創(chuàng)建產(chǎn)品對象的職責(zé)搁胆,而僅僅“消費”產(chǎn)品,簡單工廠模式實現(xiàn)了對象創(chuàng)建和使用的分離殉挽。

  • 客戶端無須知道所創(chuàng)建的具體產(chǎn)品類的類名丰涉,只需要知道具體產(chǎn)品類所對應(yīng)的參數(shù)即可,對于一些復(fù)雜的類名斯碌,通過簡單工廠模式可以在一定程度減少使用者的記憶量一死。

  • 通過引入配置文件,可以在不修改任何客戶端代碼的情況下更換和增加新的具體產(chǎn)品類傻唾,在一定程度上提高了系統(tǒng)的靈活性投慈。

2)缺點
  • 由于工廠類集中了所有產(chǎn)品的創(chuàng)建邏輯,職責(zé)過重冠骄,一旦不能正常工作伪煤,整個系統(tǒng)都要受到影響。

  • 系統(tǒng)擴展困難凛辣,一旦添加新產(chǎn)品就不得不修改工廠邏輯抱既,在產(chǎn)品類型較多時,有可能造成工廠邏輯過于復(fù)雜扁誓,不利于系統(tǒng)的擴展和維護防泵。

  • 簡單工廠模式由于使用了靜態(tài)工廠方法,造成工廠角色無法形成基于繼承的等級結(jié)構(gòu)蝗敢。

3)適用場景
  • 工廠類負責(zé)創(chuàng)建的對象比較少捷泞,由于創(chuàng)建的對象較少,不會造成工廠方法中的業(yè)務(wù)邏輯太過復(fù)雜寿谴。

  • 客戶端只知道傳入工廠類的參數(shù)锁右,對于如何創(chuàng)建對象并不關(guān)心。

暫時先寫到這讶泰,后續(xù)有時間再更新...

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末咏瑟,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子痪署,更是在濱河造成了極大的恐慌响蕴,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,214評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件惠桃,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機辜王,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,307評論 2 382
  • 文/潘曉璐 我一進店門劈狐,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人呐馆,你說我怎么就攤上這事肥缔。” “怎么了汹来?”我有些...
    開封第一講書人閱讀 152,543評論 0 341
  • 文/不壞的土叔 我叫張陵续膳,是天一觀的道長。 經(jīng)常有香客問我收班,道長坟岔,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,221評論 1 279
  • 正文 為了忘掉前任摔桦,我火速辦了婚禮社付,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘邻耕。我一直安慰自己鸥咖,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 64,224評論 5 371
  • 文/花漫 我一把揭開白布兄世。 她就那樣靜靜地躺著啼辣,像睡著了一般。 火紅的嫁衣襯著肌膚如雪御滩。 梳的紋絲不亂的頭發(fā)上鸥拧,一...
    開封第一講書人閱讀 49,007評論 1 284
  • 那天,我揣著相機與錄音艾恼,去河邊找鬼住涉。 笑死,一個胖子當(dāng)著我的面吹牛钠绍,可吹牛的內(nèi)容都是我干的舆声。 我是一名探鬼主播,決...
    沈念sama閱讀 38,313評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼柳爽,長吁一口氣:“原來是場噩夢啊……” “哼媳握!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起磷脯,我...
    開封第一講書人閱讀 36,956評論 0 259
  • 序言:老撾萬榮一對情侶失蹤蛾找,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后赵誓,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體打毛,經(jīng)...
    沈念sama閱讀 43,441評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡柿赊,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,925評論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了幻枉。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片碰声。...
    茶點故事閱讀 38,018評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖熬甫,靈堂內(nèi)的尸體忽然破棺而出胰挑,到底是詐尸還是另有隱情,我是刑警寧澤椿肩,帶...
    沈念sama閱讀 33,685評論 4 322
  • 正文 年R本政府宣布瞻颂,位于F島的核電站,受9級特大地震影響郑象,放射性物質(zhì)發(fā)生泄漏贡这。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,234評論 3 307
  • 文/蒙蒙 一扣唱、第九天 我趴在偏房一處隱蔽的房頂上張望藕坯。 院中可真熱鬧,春花似錦噪沙、人聲如沸炼彪。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,240評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽辐马。三九已至,卻和暖如春局义,著一層夾襖步出監(jiān)牢的瞬間喜爷,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,464評論 1 261
  • 我被黑心中介騙來泰國打工萄唇, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留檩帐,地道東北人。 一個月前我還...
    沈念sama閱讀 45,467評論 2 352
  • 正文 我出身青樓另萤,卻偏偏與公主長得像湃密,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子四敞,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,762評論 2 345

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