當(dāng)前位置:首頁 > 技術(shù)學(xué)院 > 技術(shù)前線
[導(dǎo)讀]工廠方法模式是一種創(chuàng)建型模式,是簡單工廠模式的一個(gè)升級(jí)版本,主要解決簡單工廠模式不符合開閉原則的問題。本文會(huì)先說一下簡單工廠模式,以及存在的問題,然后再引出工廠模式。

1. 介紹

工廠方法模式是一種創(chuàng)建型模式,是簡單工廠模式的一個(gè)升級(jí)版本,主要解決簡單工廠模式不符合開閉原則的問題。本文會(huì)先說一下簡單工廠模式,以及存在的問題,然后再引出工廠模式。

工廠設(shè)計(jì)模式是一種創(chuàng)建對(duì)象的設(shè)計(jì)模式,它的主要目的是通過定義一個(gè)接口來創(chuàng)建對(duì)象,使得子類決定實(shí)例化哪個(gè)類。這篇文章,我們將分析工廠模式是什么,它包含什么類型以及如何工作。

從整體上看,工廠模式可以分為三種主要類型:簡單工廠模式、工廠方法模式和抽象工廠模式。

1.1 簡單工廠模式

簡單工廠模式定義一個(gè)創(chuàng)建對(duì)象的類(工廠類)來負(fù)責(zé)創(chuàng)建其他對(duì)象(產(chǎn)品對(duì)象)的實(shí)例,這個(gè)類(工廠類)中的創(chuàng)建功能根據(jù)參數(shù)不同,創(chuàng)建不同的對(duì)象(產(chǎn)品對(duì)象)實(shí)例。這就存在一個(gè)問題,每增加一個(gè)產(chǎn)品類,就要修改工廠的創(chuàng)建邏輯,增加一個(gè)相應(yīng)的產(chǎn)品對(duì)象創(chuàng)建,這違反了程序設(shè)計(jì)的開閉原則。

概述

簡單工廠模式并不是一個(gè)正式的設(shè)計(jì)模式,而是一個(gè)創(chuàng)建對(duì)象的簡單方法。在簡單工廠模式中,通常會(huì)有一個(gè)工廠類,它根據(jù)參數(shù)的不同返回不同類型的對(duì)象。這個(gè)模式的優(yōu)點(diǎn)是簡單明了,但缺點(diǎn)是違背了開閉原則。

角色

工廠類:負(fù)責(zé)創(chuàng)建產(chǎn)品的實(shí)例,提供一個(gè)靜態(tài)方法供外部調(diào)用。

產(chǎn)品類:所有產(chǎn)品類都需實(shí)現(xiàn)相同的接口,用于定義產(chǎn)品的公共行為。

客戶端:通過工廠類來獲取產(chǎn)品實(shí)例,并使用這些實(shí)例。

設(shè)計(jì)模式之簡單工廠模式(C#語言描述)

嚴(yán)格意義上來說,簡單工廠模式并不屬于GoF的23種設(shè)計(jì)模式,但是它是學(xué)習(xí)其他工廠模式的基礎(chǔ)和前提條件。理解了簡單工廠模式,學(xué)習(xí)工廠方法模式和抽象工廠模式會(huì)比較容易一些。

簡單工廠模式的定義

定義一個(gè)工廠類,他可以根據(jù)不同的參數(shù)返回不同類的實(shí)例。通常情況下,被創(chuàng)建的類的實(shí)例通常都具有共同的父類。

簡單工廠模式又可以稱之為靜態(tài)工廠方法模式,因?yàn)閯?chuàng)建對(duì)象實(shí)例的方法通常都是靜態(tài)方法。

在簡單工廠模式中,只需要記住一點(diǎn)。一個(gè)簡單的參數(shù)可以即可獲得所需的對(duì)象實(shí)例。

簡單工廠模式的UML圖如下:

簡單工廠模式包含三個(gè)角色:

1、工廠角色(Factory):該類是簡單工廠的核心,我們所需要的對(duì)象實(shí)例就是這個(gè)類幫我們創(chuàng)建的,它里面有一個(gè)靜態(tài)方法GetProduct(string productType),我們通過傳入產(chǎn)品類型(productType)來得到我們想要的產(chǎn)品。

2、抽象產(chǎn)品角色(AbstractProduct):該類是所有產(chǎn)品的父類。它可以是接口或者抽象類。只有這樣我們才能給工廠的GetProduct(string productType)方法定義返回值。

3、實(shí)體產(chǎn)品(ConcreteProductA,ConcreteProductB,ConcreteProductC):這些類是簡單工廠最終要?jiǎng)?chuàng)建的目標(biāo),也是客戶端最終想要的對(duì)象實(shí)例。

現(xiàn)在來假設(shè)一種場(chǎng)景,我們開發(fā)過程中,肯定會(huì)用到按鈕,圓形按鈕、正方形按鈕、矩形按鈕等等,在程序的很多地方我們都可能會(huì)復(fù)用這些按鈕。我們可以通過一個(gè)簡單工廠來幫助我們創(chuàng)建這些按鈕。

簡單工廠模式的類圖

SimpleFactory是個(gè)工廠類,負(fù)責(zé)創(chuàng)建對(duì)象(具體的工廠)。Product是要?jiǎng)?chuàng)建產(chǎn)品的抽象類,負(fù)責(zé)定義統(tǒng)一的接口。ProductA和ProductB是具體的產(chǎn)品類型,是Product的實(shí)現(xiàn)。我們看一下簡單工廠模式的優(yōu)缺點(diǎn)。

簡單工廠模式優(yōu)點(diǎn):

實(shí)現(xiàn)簡單、結(jié)構(gòu)清晰。抽象出一個(gè)專門的工廠類來負(fù)責(zé)某類工廠對(duì)象的創(chuàng)建。使用者可以不關(guān)注具體工廠對(duì)象的類名,只要傳入相應(yīng)的參數(shù)就能創(chuàng)建對(duì)應(yīng)的工廠對(duì)象。簡單工廠模式的缺點(diǎn):

不易擴(kuò)展,一旦新增產(chǎn)品類型,就得修改工廠的創(chuàng)建邏輯,不符合開閉原則。當(dāng)產(chǎn)品類型較多的時(shí)候,工廠創(chuàng)建邏輯會(huì)過于復(fù)雜,不利于維護(hù)。簡單工廠模式的應(yīng)用場(chǎng)景:

產(chǎn)品具有明顯的繼承關(guān)系,并且產(chǎn)品的類型不多或有限。所有的產(chǎn)品具體有相同的方法和類似的屬性,使用者不關(guān)心具體的類型,只希望傳入合適的參數(shù),然后返回合適的工廠對(duì)象。1.2 工廠方法模式

為了解決簡單工廠存在的,新增產(chǎn)品類型,就修改工廠的創(chuàng)建邏輯的問題。提出了工廠方法模式。工廠方法模式定義了一個(gè)創(chuàng)建對(duì)象(產(chǎn)品對(duì)象)的接口,讓子類(工廠類)來決定創(chuàng)建哪個(gè)類(產(chǎn)品類)的實(shí)例。它是一個(gè)類(工廠類)的實(shí)例化,延遲到其子類。

Product是要?jiǎng)?chuàng)建產(chǎn)品的抽象類,ProductA和ProductB是具體的產(chǎn)品類型。Factory是所有工廠的抽象類,負(fù)責(zé)定義統(tǒng)一的接口。ProductAFactory和ProductBFactory是具體的工廠類,分別負(fù)責(zé)產(chǎn)品ProductA和ProductB的創(chuàng)建。工廠方法類利用依賴倒置原則,高層模塊不依賴于底層的模塊,它們應(yīng)該依賴于抽象,面向接口編程,從而解決了簡單工廠模式違反軟件設(shè)計(jì)的開閉原則的問題。工廠方法模式也有一些優(yōu)缺點(diǎn),接下來我們看一下。

工廠方法模式的優(yōu)點(diǎn):

解決了簡單工廠模式違反開閉原則的問題,使程序擴(kuò)展性增強(qiáng)。工廠方法模式的缺點(diǎn):

對(duì)于由多種分類(存在不同的分類方式組合)的產(chǎn)品,或者具有二級(jí)分類的產(chǎn)品,工廠方法模式不適用。工廠方法模式的應(yīng)用場(chǎng)景:

客戶端不知道它所需要的對(duì)象的類。工廠類希望通過其子類來決定創(chuàng)建哪個(gè)具體類的對(duì)象。2, 舉例

一般主程序只關(guān)注業(yè)務(wù)邏輯(抽象類接口),不關(guān)心具體的業(yè)務(wù)細(xì)節(jié)(抽象類接口的具體實(shí)現(xiàn))。這些業(yè)務(wù)細(xì)節(jié)就可以放在創(chuàng)建對(duì)象的邏輯(工廠創(chuàng)建邏輯)中,主程序只要設(shè)置指定的參數(shù),就能通過創(chuàng)建對(duì)象的邏輯獲取相應(yīng)對(duì)象(工廠對(duì)象)。

接下來會(huì)分別舉例說明簡單工廠模式、工廠方法模式的C語言實(shí)現(xiàn)。

2.1 簡單工廠模式舉例

#include

#include

enum {

PRODUCTA = 1,

PRODUCTB,

PRODUCTC,

};

// define product interface

typedef struct Product {

void (*show)(struct Product*);

} Product;

// define specific productA class

typedef struct ProductA {

Product product;

} ProductA;

// define productA show function

void ProductA_show(Product* product) {

printf("This is ProductA\n");

}

// define specific productB class

typedef struct ProductB {

Product product;

} ProductB;

// define productB show function

void ProductB_show(Product* product) {

printf("This is ProductB\n");

}

// define factory class

typedef struct Factory {

Product* (*create_product)(int);

} Factory;

// define factory create product logic

Product* factory_create_product(int type) {

Product* product = NULL;

switch (type) {

case 1:

product = (Product*)malloc(sizeof(ProductA));

product->show = ProductA_show;

break;

case 2:

product = (Product*)malloc(sizeof(ProductB));

product->show = ProductB_show;

break;

default:

printf("Invalid product type\n");

break;

}

return product;

}

int main() {

// implement factory instance

Factory simple_factory = { factory_create_product };

// use factory instance to create specific productA

Product* productA = simple_factory.create_product(PRODUCTA);

productA->show(productA);

free(productA);

// use factory instance to create specific productB

Product* productB = simple_factory.create_product(PRODUCTB);

productB->show(productB);

free(productB);

// use factory instance to create specific productC

Product* productC = simple_factory.create_product(PRODUCTC);

if (productC != NULL) {

free(productC);

}

return 0;

}

在這個(gè)例子中,定義了一個(gè)產(chǎn)品接口(Product)和兩個(gè)具體產(chǎn)品類(ProductA 和 ProductB),這兩個(gè)具體的產(chǎn)品類都實(shí)現(xiàn)了產(chǎn)品接口。此外,還定義了一個(gè)工廠類(Factory),它有一個(gè) create_product 方法,通過該方法可以根據(jù)傳入的參數(shù)創(chuàng)建不同類型的產(chǎn)品對(duì)象。

在 main 函數(shù)中,使用工廠類實(shí)例化了一個(gè)工廠對(duì)象,然后用這個(gè)工廠對(duì)象創(chuàng)建了具體產(chǎn)品對(duì)象ProductA 和ProductB,并調(diào)用它們的 show 方法打印出相應(yīng)的信息。當(dāng)傳入一個(gè)無效的參數(shù)時(shí),工廠類會(huì)打印出錯(cuò)誤信息。

2.2 工廠方法模式舉例

#include

#include

// define product interface

typedef struct Product {

void (*show)(struct Product*);

} Product;

// define specific productA class

typedef struct ProductA {

Product product;

} ProductA;

// define productA show function

void ProductA_show(Product* product) {

printf("This is ProductA\n");

}

// define specific productB class

typedef struct ProductB {

Product product;

} ProductB;

// define productB show function

void ProductB_show(Product* product) {

printf("This is ProductB\n");

}

// define factory interface

typedef struct Factory {

Product* (*create_product)(struct Factory*);

} Factory;

// define specific factoryA class

typedef struct FactoryA {

Factory factory;

} FactoryA;

// inplement factoryA create_product function

Product* factoryA_create_product(Factory* factory) {

Product* product = (Product*)malloc(sizeof(Product));

product->show = ProductA_show;

return product;

}

// define specific factoryB class

typedef struct FactoryB {

Factory factory;

} FactoryB;

// inplement factoryB create_product function

Product* factoryB_create_product(Factory* factory) {

Product* product = (Product*)malloc(sizeof(Product));

product->show = ProductB_show;

return product;

}

int main() {

// create specific factoryA instance

FactoryA FactoryA;

FactoryA.factory.create_product = factoryA_create_product;

// create specific factoryB instance

FactoryB FactoryB;

FactoryB.factory.create_product = factoryB_create_product;

// use specific factory instance create specific product

Product* productA = FactoryA.factory.create_product(&FactoryA.factory);

productA->show(productA);

free(productA);

// use specific factory instance create specific product

Product* productB = FactoryB.factory.create_product(&FactoryB.factory);

productB->show(productB);

free(productB);

return 0;

}

在這個(gè)例子中,定義了一個(gè)產(chǎn)品接口(Product)和兩個(gè)具體產(chǎn)品類(ProductA 和 ProductB),這兩個(gè)具體的產(chǎn)品類都實(shí)現(xiàn)了產(chǎn)品接口。另外,還定義了一個(gè)工廠接口(Factory)和兩個(gè)具體工廠類(FactoryA 和 FactoryB),它們都實(shí)現(xiàn)了工廠接口。每個(gè)具體工廠類都有一個(gè)創(chuàng)建產(chǎn)品的方法,通過該方法可以創(chuàng)建相應(yīng)的產(chǎn)品對(duì)象。

在 main 函數(shù)中,首先創(chuàng)建了具體工廠對(duì)象FactoryA 和 FactoryB,然后通過它們的create_product方法分別創(chuàng)建了具體產(chǎn)品對(duì)象ProductA 和ProductB。最后,使用 free 函數(shù)釋放了創(chuàng)建的產(chǎn)品對(duì)象。

本站聲明: 本文章由作者或相關(guān)機(jī)構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點(diǎn),本站亦不保證或承諾內(nèi)容真實(shí)性等。需要轉(zhuǎn)載請(qǐng)聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請(qǐng)及時(shí)聯(lián)系本站刪除。
換一批
延伸閱讀

9月2日消息,不造車的華為或?qū)⒋呱龈蟮莫?dú)角獸公司,隨著阿維塔和賽力斯的入局,華為引望愈發(fā)顯得引人矚目。

關(guān)鍵字: 阿維塔 塞力斯 華為

倫敦2024年8月29日 /美通社/ -- 英國汽車技術(shù)公司SODA.Auto推出其旗艦產(chǎn)品SODA V,這是全球首款涵蓋汽車工程師從創(chuàng)意到認(rèn)證的所有需求的工具,可用于創(chuàng)建軟件定義汽車。 SODA V工具的開發(fā)耗時(shí)1.5...

關(guān)鍵字: 汽車 人工智能 智能驅(qū)動(dòng) BSP

北京2024年8月28日 /美通社/ -- 越來越多用戶希望企業(yè)業(yè)務(wù)能7×24不間斷運(yùn)行,同時(shí)企業(yè)卻面臨越來越多業(yè)務(wù)中斷的風(fēng)險(xiǎn),如企業(yè)系統(tǒng)復(fù)雜性的增加,頻繁的功能更新和發(fā)布等。如何確保業(yè)務(wù)連續(xù)性,提升韌性,成...

關(guān)鍵字: 亞馬遜 解密 控制平面 BSP

8月30日消息,據(jù)媒體報(bào)道,騰訊和網(wǎng)易近期正在縮減他們對(duì)日本游戲市場(chǎng)的投資。

關(guān)鍵字: 騰訊 編碼器 CPU

8月28日消息,今天上午,2024中國國際大數(shù)據(jù)產(chǎn)業(yè)博覽會(huì)開幕式在貴陽舉行,華為董事、質(zhì)量流程IT總裁陶景文發(fā)表了演講。

關(guān)鍵字: 華為 12nm EDA 半導(dǎo)體

8月28日消息,在2024中國國際大數(shù)據(jù)產(chǎn)業(yè)博覽會(huì)上,華為常務(wù)董事、華為云CEO張平安發(fā)表演講稱,數(shù)字世界的話語權(quán)最終是由生態(tài)的繁榮決定的。

關(guān)鍵字: 華為 12nm 手機(jī) 衛(wèi)星通信

要點(diǎn): 有效應(yīng)對(duì)環(huán)境變化,經(jīng)營業(yè)績穩(wěn)中有升 落實(shí)提質(zhì)增效舉措,毛利潤率延續(xù)升勢(shì) 戰(zhàn)略布局成效顯著,戰(zhàn)新業(yè)務(wù)引領(lǐng)增長 以科技創(chuàng)新為引領(lǐng),提升企業(yè)核心競爭力 堅(jiān)持高質(zhì)量發(fā)展策略,塑強(qiáng)核心競爭優(yōu)勢(shì)...

關(guān)鍵字: 通信 BSP 電信運(yùn)營商 數(shù)字經(jīng)濟(jì)

北京2024年8月27日 /美通社/ -- 8月21日,由中央廣播電視總臺(tái)與中國電影電視技術(shù)學(xué)會(huì)聯(lián)合牽頭組建的NVI技術(shù)創(chuàng)新聯(lián)盟在BIRTV2024超高清全產(chǎn)業(yè)鏈發(fā)展研討會(huì)上宣布正式成立。 活動(dòng)現(xiàn)場(chǎng) NVI技術(shù)創(chuàng)新聯(lián)...

關(guān)鍵字: VI 傳輸協(xié)議 音頻 BSP

北京2024年8月27日 /美通社/ -- 在8月23日舉辦的2024年長三角生態(tài)綠色一體化發(fā)展示范區(qū)聯(lián)合招商會(huì)上,軟通動(dòng)力信息技術(shù)(集團(tuán))股份有限公司(以下簡稱"軟通動(dòng)力")與長三角投資(上海)有限...

關(guān)鍵字: BSP 信息技術(shù)
關(guān)閉