工廠方法模式

1、定義

工廠方法模式(FACTORY METHOD)是一種常用的類創(chuàng)建型設(shè)計(jì)模式,此模式的核心精神是封裝類中變化的部分,提取其中個性化善變的部分為獨(dú)立類,通過依賴注入以達(dá)到解耦、復(fù)用和方便后期維護(hù)拓展的目的。它的核心結(jié)構(gòu)有四個角色,分別是抽象工廠;具體工廠;抽象產(chǎn)品;具體產(chǎn)品

2、模式簡介

工廠方法(Factory Method)模式的意義是定義一個創(chuàng)建產(chǎn)品對象的工廠接口,將實(shí)際創(chuàng)建工作推遲到子類當(dāng)中。核心工廠類不再負(fù)責(zé)產(chǎn)品的創(chuàng)建,這樣核心類成為一個抽象工廠角色,僅負(fù)責(zé)具體工廠子類必須實(shí)現(xiàn)的接口,這樣進(jìn)一步抽象化的好處是使得工廠方法模式可以使系統(tǒng)在不修改具體工廠角色的情況下引進(jìn)新的產(chǎn)品。

工廠方法模式是簡單工廠模式的衍生,解決了許多簡單工廠模式的問題。首先完全實(shí)現(xiàn)‘開-閉 原則’,實(shí)現(xiàn)了可擴(kuò)展。其次更復(fù)雜的層次結(jié)構(gòu),可以應(yīng)用于產(chǎn)品結(jié)果復(fù)雜的場合。

工廠方法模式對簡單工廠模式進(jìn)行了抽象。有一個抽象的Factory類(可以是抽象類和接口),這個類將不再負(fù)責(zé)具體的產(chǎn)品生產(chǎn),而是只制定一些規(guī)范,具體的生產(chǎn)工作由其子類去完成。在這個模式中,工廠類和產(chǎn)品類往往可以依次對應(yīng)。即一個抽象工廠對應(yīng)一個抽象產(chǎn)品,一個具體工廠對應(yīng)一個具體產(chǎn)品,這個具體的工廠就負(fù)責(zé)生產(chǎn)對應(yīng)的產(chǎn)品。

工廠方法模式(Factory Method pattern)是最典型的模板方法模式(Template Method pattern)應(yīng)用。

3、角色結(jié)構(gòu)

抽象工廠(Creator)角色

是工廠方法模式的核心,與應(yīng)用程序無關(guān)。任何在模式中創(chuàng)建的對象的工廠類必須實(shí)現(xiàn)這個接口。

具體工廠(Concrete Creator)角色

這是實(shí)現(xiàn)抽象工廠接口的具體工廠類,包含與應(yīng)用程序密切相關(guān)的邏輯,并且受到應(yīng)用程序調(diào)用以創(chuàng)建產(chǎn)品對象。

抽象產(chǎn)品(Product)角色

工廠方法模式所創(chuàng)建的對象的超類型,也就是產(chǎn)品對象的共同父類或共同擁有的接口

具體產(chǎn)品(Concrete Product)角色

這個角色實(shí)現(xiàn)了抽象產(chǎn)品角色所定義的接口。某具體產(chǎn)品有專門的具體工廠創(chuàng)建,它們之間往往一一對應(yīng)。

4、模式應(yīng)用

工廠方法經(jīng)常用在以下兩種情況中:

第一種情況是對于某個產(chǎn)品,調(diào)用者清楚地知道應(yīng)該使用哪個具體工廠服務(wù),實(shí)例化該具體工廠,生產(chǎn)出具體的產(chǎn)品來。Java Collection中的iterator() 方法即屬于這種情況。

第二種情況,只是需要一種產(chǎn)品,而不想知道也不需要知道究竟是哪個工廠為生產(chǎn)的,即最終選用哪個具體工廠的決定權(quán)在生產(chǎn)者一方,它們根據(jù)當(dāng)前系統(tǒng)的情況來實(shí)例化一個具體的工廠返回給使用者,而這個決策過程這對于使用者來說是透明的。

--以上概念摘抄自百度百科,方便自己學(xué)習(xí)--

-----------------------------------------------------------------------------------

--開始自己擼--

5、實(shí)例講解

背景:比如說我現(xiàn)在有這么個需求,就是我要對面粉進(jìn)行加工,從而得到饅頭、掛面

首先我需要抽象產(chǎn)品(Product)角色

/**
 * 首先無論是做饅頭還是掛面,他們都有一個加工方法,可以抽象出來
 * Machine:機(jī)器
 */
public interface MachineApi {
        //process:加工      material:材料
    public void process(String material);
    
}

然后我需要拿到具體產(chǎn)品

/**
 * 饅頭機(jī)器
 * steamed bun : 饅頭
 */
public class SteamedBunMachine implements MachineApi {
    @Override
    public void process(String material) {
        System.out.println("我把" + material + "加工成了饅頭");
    }
}

/**
 * 面條機(jī)器
 * noodle : 面條
 */
public class BoodleMachine implements MachineApi {
    @Override
    public void process(String material) {
        System.out.println("我把" + material + "加工成了面條");
    }
}

這個時候我需要一個 抽象工廠角色

public abstract class Factory{
    /**
     * 讓子類(具體工廠)來實(shí)例化具體對象(機(jī)器)
     */
    public abstract MachineApi newMachine();
    
    /**
     * 加工材料
     */
    public void process(String material){
        MachineApi machine = newMachine();
        machine.process(material);
    }
    
}

然后我需要兩家工廠,分別幫我生成饅頭和面條

//饅頭工廠
public class SteamedBunFactory extends Factory{
    //饅頭工廠,只需要提供饅頭機(jī)器就行
    @Override
    public MachineApi newMachine() {
        return new SteamedBunMachine();
    }
}

//面條工廠
public class NoodleFactory extends Factory{
    //面條工廠,只需要提供面條機(jī)器就行
    @Override
    public MachineApi newMachine() {
        return new BoodleMachine();
    }
}

最后我作為老板,只需要操作工廠就可以進(jìn)行生成

SteamedBunFactory mSteamedBunFactory  = new SteamedBunFactory ();
mSteamedBunFactory.process("面粉");//我把面粉加工成了饅頭

總結(jié)

其實(shí)這個時候,我作為老板,我又想開一家餅干廠,那么我只需要弄一臺餅干機(jī)器(繼承機(jī)器),再弄一個餅干廠(繼承工廠)就可以了,根本不需要動之前的代碼,這個過程唯一變化的就是做饅頭和做面條的流程工藝不同,提取其中個性化善變的部分為獨(dú)立類,通過依賴注入以達(dá)到解耦、復(fù)用和方便后期維護(hù)拓展的目的。
版權(quán)聲明:個人原創(chuàng),若轉(zhuǎn)載,請注明出處
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

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