
原文地址:LoveDev
工廠模式是最常用的設(shè)計(jì)模式之一,該模式定義一個(gè)用于創(chuàng)建對(duì)象的工廠類,調(diào)用者不用關(guān)心創(chuàng)建的細(xì)節(jié)
工廠模式可以分為三個(gè)子模式:
- 簡(jiǎn)單工廠模式(Simple Creational Pattern)
- 工廠方法模式(Factory Creational Pattern)
- 抽象工廠模式(Abstract Creational Pattern)
<h1 id="SCP"> 簡(jiǎn)單工廠模式 </h1>
定義工廠類,根據(jù)參數(shù)返回不同類的實(shí)例,這些實(shí)例通常具有共同的父類,因?yàn)楹?jiǎn)單工廠模式用靜態(tài)方法創(chuàng)建實(shí)例,所以又稱為靜態(tài)工廠模式(Static Creational Pattern)

- Factory:工廠類,實(shí)現(xiàn)創(chuàng)建所有產(chǎn)品實(shí)例的內(nèi)部邏輯
- Product:抽象產(chǎn)品類,封裝產(chǎn)品公有方法,它的引入使得工廠類只需要定義一個(gè)通用的工廠方法,因?yàn)閯?chuàng)建的具體產(chǎn)品都是該類的子類
- ConcreteProduct:具體實(shí)現(xiàn)類
代碼示例:
產(chǎn)品類:
// 抽象產(chǎn)品類
abstract class Product {
abstract void doSomething(Context context);
}
// 具體產(chǎn)品類
class ConcreteProduct extends Product {
@Override
void doSomething(Context context) {
}
}
工廠類:
class Factory {
public Factory() {
throw new RuntimeException("can't init");
}
static final String concreteProductA = "concreteProductA";
static final String concreteProductB = "concreteProductB";
static Product createdProduct(String arg) {
switch (arg) {
case concreteProductA:
return new ConcreteProductA();
case concreteProductB:
return new ConcreteProductB();
default:
return null;
}
}
}
適用場(chǎng)景:
- 工廠類負(fù)責(zé)創(chuàng)建的對(duì)象比較少,由于創(chuàng)建的對(duì)象較少,不會(huì)造成工廠方法中的業(yè)務(wù)邏輯太過(guò)復(fù)雜
- 客戶端只知道傳入工廠類的參數(shù),對(duì)于如何創(chuàng)建對(duì)象并不關(guān)心
現(xiàn)實(shí)情況是復(fù)雜多變的,突然有一天產(chǎn)品經(jīng)理說(shuō)還要增加一個(gè)其他的類型,如果是簡(jiǎn)單工廠方法,就不得不在 if...else
或者 switch
中增加一個(gè)判斷,這樣就違反了開(kāi)閉原則,對(duì)于這樣的工廠類,稱它為全能類或者上帝類
<h1 id="FCP"> 工廠方法模式 </h1>
工廠方法模式去掉簡(jiǎn)單工廠模式的靜態(tài)方法,使它可以被子類繼承,這樣就可以把靜態(tài)方法的壓力分擔(dān)給各個(gè)子類承擔(dān),每個(gè)子工廠類只負(fù)責(zé)創(chuàng)建一個(gè)具體的產(chǎn)品類實(shí)例

- Product:抽象產(chǎn)品類,所有需要實(shí)例化子類的父類
- ConcreteProduct:具體產(chǎn)品類
- Factory:抽象工廠類,此類是工廠方法模式的核心,所有工廠類都要繼承該類
- ConcreteFactory:具體工廠類,實(shí)現(xiàn)具體的業(yè)務(wù)邏輯
示例代碼:
產(chǎn)品類:
// 抽象類
abstract class People {
abstract void doSomething();
}
// 女性
class Female extends People{
@Override
void doSomething() {
}
}
// 男性
class Male extends People {
@Override
void doSomething() {
}
}
工廠類:
// 抽象工廠類
public abstract class Factory {
abstract People createPeople();
}
// 具體工廠類
public class FemaleFactory extends Factory {
@Override
People createPeople() {
return new Female();
}
}
public class MaleFactory extends Factory {
@Override
People createPeople() {
return new Male();
}
}
適用場(chǎng)景:
- 客戶端不知道它所需要的對(duì)象的類。在工廠方法模式中,客戶端不需要知道具體產(chǎn)品類的類名,只需要知道所對(duì)應(yīng)的工廠即可,具體的產(chǎn)品對(duì)象由具體工廠類創(chuàng)建
- 抽象工廠類通過(guò)其子類來(lái)指定創(chuàng)建哪個(gè)對(duì)象。在工廠方法模式中,對(duì)于抽象工廠類只需要提供一個(gè)創(chuàng)建產(chǎn)品的接口,而由其子類來(lái)確定具體要?jiǎng)?chuàng)建的對(duì)象,利用面向?qū)ο蟮亩鄳B(tài)性和里氏代換原則,在程序運(yùn)行時(shí),子類對(duì)象將覆蓋父類對(duì)象,從而使得系統(tǒng)更容易擴(kuò)展
跟簡(jiǎn)單工廠模式一樣的問(wèn)題,雖然沒(méi)有違反開(kāi)閉原則,但是增加新產(chǎn)品類的時(shí)候,因?yàn)橐粋€(gè)具體工廠類只負(fù)責(zé)一個(gè)具體產(chǎn)品類,所以必須也要增加對(duì)應(yīng)的具體工廠類,項(xiàng)目中類的個(gè)數(shù)成對(duì)增加,進(jìn)而增加了系統(tǒng)的復(fù)雜度,更多的類需要編譯和運(yùn)行,給系統(tǒng)帶來(lái)額外的開(kāi)銷
<h1 id="ACP"> 抽象工廠模式 </h1>
工廠方法模式中一個(gè)工廠類負(fù)責(zé)生產(chǎn)一個(gè)具體產(chǎn)品,有時(shí)根據(jù)業(yè)務(wù)需求,一個(gè)工廠類需要提供多個(gè)具體產(chǎn)品,例如生產(chǎn)共享單車(chē),一個(gè)工廠類可以提供多個(gè)共享單車(chē)的組件,比如車(chē)胎,車(chē)架,車(chē)座,車(chē)把,從而組成一個(gè)完整產(chǎn)品,為了更好理解抽象工廠模式,先理解兩個(gè)概念:
- 產(chǎn)品等級(jí)結(jié)構(gòu):即產(chǎn)品的繼承結(jié)構(gòu),如車(chē)輪,子類有實(shí)心車(chē)胎,充氣車(chē)胎,山地車(chē)胎等,抽象車(chē)輪和車(chē)輪具體類型構(gòu)成一個(gè)產(chǎn)品等級(jí)結(jié)構(gòu)
- 產(chǎn)品族:抽象工廠模式中,產(chǎn)品族指同一工廠生產(chǎn)的,位于不同產(chǎn)品等級(jí)結(jié)構(gòu)的一組產(chǎn)品,如自行車(chē)廠商生產(chǎn)實(shí)心車(chē)胎、鋁合金車(chē)架等,實(shí)心車(chē)胎位于車(chē)胎產(chǎn)品等級(jí)結(jié)構(gòu)中,鋁合金車(chē)架位于車(chē)架產(chǎn)品等級(jí)結(jié)構(gòu)中,實(shí)心車(chē)胎、鋁合金車(chē)架等構(gòu)成一個(gè)產(chǎn)品族

- AbstractProductA:抽象產(chǎn)品類
- AbstractProductB:抽象產(chǎn)品類
- ConcreteProductA1:具體產(chǎn)品類
- ConcreteProductA2:具體產(chǎn)品類
- ConcreteProductB1:具體產(chǎn)品類
- ConcreteProductB2:具體產(chǎn)品類
- AbstractFactory:抽象工廠類
- ConcreteFactory1:具體工廠類,實(shí)現(xiàn)具體的業(yè)務(wù)邏輯
- ConcreteFactory2:具體工廠類,實(shí)現(xiàn)具體的業(yè)務(wù)邏輯
這里用一個(gè)生產(chǎn)單車(chē)的例子實(shí)踐一下抽象工廠模式,示例代碼:
產(chǎn)品類:
// 車(chē)座
interface ISeat {
void seat();
}
// 車(chē)胎
interface ITire {
void tire();
}
// 車(chē)架
interface IFrame {
void frame();
}
// 鋁合金車(chē)架
public class AlloyFrame implements IFrame {
@Override
public void frame() {
Log.i("IFrame", "AlloyFrame");
}
}
// 碳纖維車(chē)架
class CarbonFrame implements IFrame {
@Override
public void frame() {
Log.i("IFrame", "CarbonFrame");
}
}
// 真皮車(chē)座
class DermisSeat implements ISeat {
@Override
public void seat() {
Log.i("ISeat", "DermisSeat");
}
}
// 橡膠車(chē)座
class RubberSeat implements ISeat {
@Override
public void seat() {
Log.i("ISeat", "RubberSeat");
}
}
// 充氣車(chē)胎
class InflateTire implements ITire {
@Override
public void tire() {
Log.i("ITire", "InflateTire");
}
}
// 實(shí)心車(chē)胎
class SolidTire implements ITire {
@Override
public void tire() {
Log.i("ITire", "SolidTire");
}
}
工廠類:
// 抽象工廠類
abstract class AbstractFactory {
/**
* 生產(chǎn)車(chē)胎
*
* @return 車(chē)胎
*/
abstract ITire createTire();
/**
* 生產(chǎn)車(chē)架
*
* @return 車(chē)架
*/
abstract IFrame createFrame();
/**
* 生產(chǎn)車(chē)座
*
* @return 車(chē)座
*/
abstract ISeat createSeat();
}
// ofo 工廠類
class OfoFactory extends AbstractFactory {
@Override
ITire createTire() {
return new InflateTire();
}
@Override
IFrame createFrame() {
return new CarbonFrame();
}
@Override
ISeat createSeat() {
return new RubberSeat();
}
}
// mobike 工廠類
class MobikeFactory extends AbstractFactory{
@Override
ITire createTire() {
return new SolidTire();
}
@Override
IFrame createFrame() {
return new AlloyFrame();
}
@Override
ISeat createSeat() {
return new DermisSeat();
}
}
適用場(chǎng)景:
- 一個(gè)系統(tǒng)不應(yīng)當(dāng)依賴于產(chǎn)品類實(shí)例如何被創(chuàng)建、組合和表達(dá)的細(xì)節(jié),這對(duì)于所有類型的工廠模式都是很重要的,用戶無(wú)須關(guān)心對(duì)象的創(chuàng)建過(guò)程,將對(duì)象的創(chuàng)建和使用解耦
- 系統(tǒng)中有多于一個(gè)的產(chǎn)品族,而每次只使用其中某一產(chǎn)品族
- 產(chǎn)品等級(jí)結(jié)構(gòu)穩(wěn)定,設(shè)計(jì)完成之后,不會(huì)向系統(tǒng)中增加新的產(chǎn)品等級(jí)結(jié)構(gòu)或者刪除已有的產(chǎn)品等級(jí)結(jié)構(gòu)
抽象工廠模式可以很方便根據(jù)現(xiàn)有的產(chǎn)品等級(jí)結(jié)構(gòu)生成新的產(chǎn)品族,但是增加新的產(chǎn)品等級(jí)結(jié)構(gòu)會(huì)很麻煩,這種性質(zhì)稱為開(kāi)閉原則的傾斜性