淺談工廠模式(簡單工廠 工廠方法 抽象工廠)

今天和大家分享一下設(shè)計(jì)模式中的 簡單工廠 工廠方法 抽象工廠

工廠模式百度百科截圖.png

上圖是工廠模式百度百科的截圖,工廠模式(三種模式)的目的在于程序的可擴(kuò)展性,便于維護(hù)減少開發(fā)出錯(cuò),本人總結(jié)為工廠模式就是讓類的創(chuàng)建使用分離,降低程序模塊之間的耦合程度(歡迎提出質(zhì)疑)


1.簡單工廠模式(Simple Factory Pattern)

我這里來拿《大話設(shè)計(jì)模式》中“大鳥”指導(dǎo)“小菜”完成的一個(gè)簡單工廠來舉例子(編寫一個(gè)簡單的計(jì)算器程序),這里我把他的c#代碼換成了本人學(xué)習(xí)的java -- ps:本人也是剛畢業(yè)不久的菜鳥一枚,正在看這本書就當(dāng)是寫個(gè)個(gè)人總結(jié)和大家分享一下。這本書評(píng)價(jià)不錯(cuò)京東有正版有能力的朋友可以支持一下作者。也可以看網(wǎng)絡(luò)上的pdf.....
首先來分析一下計(jì)算器程序的目的是為了得到一個(gè)計(jì)算結(jié)果,我們應(yīng)該抽象出這個(gè)結(jié)果首先我們是我們的抽象接口代碼

public interface Operation {

    public  double getResult(double number_a,double number_b);

}

Operation 接口中一個(gè)getResult 參數(shù)為 兩個(gè)double數(shù)。
假設(shè)目前只要滿足 + - * /的計(jì)算 好了我們來新建四個(gè)計(jì)算的運(yùn)算類分別實(shí)現(xiàn)接口Operation

public class  OperationAdd implements Operation{
    @Override
    public double getResult(double number_a, double number_b) {
        double result=0;
        result= number_a+number_b;
        return  result;
    }
}
public  class  OperationMul implements Operation{

    @Override
    public double getResult(double number_a,double number_b) {
        double result=0;
        result=number_a*number_b;
        return result;
    }
}
public class OperationSub implements Operation{

    @Override
    public double getResult(double number_a,double number_b) {
        double result=0;
        result= number_a-number_b;
        return  result;
    }
}
public  class  OperationDiv implements Operation{

    @Override
    public double getResult(double number_a,double number_b) {
        double result=0;
        if(number_b==0)
        {
            try {
                throw new Exception("除數(shù)不能為零");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        result=number_a/number_b;
        return result;
    }
}

這里大家是不是萬事具備只欠東風(fēng)了呢,問題來了具體的運(yùn)算類怎么調(diào)用 何時(shí)調(diào)用誰呢,這時(shí)間我們把我們的重點(diǎn)工廠類請出來了,讓它決定我們怎么使用具體的運(yùn)算類

public class OperationFactory  {
    private static OperationFactory instance ;

    private OperationFactory(){}

    public  static OperationFactory getInstance(){
        if (instance == null) {
            synchronized (OperationFactory.class){
                if (instance == null) {
                    instance = new OperationFactory();
                }
            }
        }
        return instance ;
    }

    public    Operation createOperation(String operator){
        Operation operation=null;
        switch (operator)
        {
            case "+":
                operation=new OperationAdd();
                break;
            case "-":
                operation=new OperationSub();
                break;
            case "*":
                operation=new OperationMul();
                break;
            case "/":
                operation=new OperationDiv();
                break;
            default:
                try {
                    throw    new Exception("請輸入正確的運(yùn)算符");
                } catch (Exception e) {
                    e.printStackTrace();
                }
                break;
        }
        return  operation;
    }

    public Operation makeOperation(Class c)
    {
        Operation operation=null;
        try {
            operation=(Operation) Class.forName(c.getName()).newInstance();
        }catch (InstantiationException e) {

            System.out.println("不支持抽象類或接口");
            e.printStackTrace();
        } catch (IllegalAccessException e) {

            e.printStackTrace();
            System.out.println("沒有足夠權(quán)限,即不能訪問私有對(duì)象");
        } catch (ClassNotFoundException e) {

            System.out.println("類不存在");
            e.printStackTrace();
        } catch (ClassCastException e)
        {
            System.out.println("選擇的類不正確");
        }
        return operation;
    }
}

我們先不管makeOperation方法先看createOperation方法。
createOperation只需要在調(diào)用的時(shí)間接受operator參數(shù)(+-*/)就能返回所對(duì)應(yīng)的運(yùn)算類了
下面是客戶端代碼

public class Main {
    public static void main(String[] args) {
        Operation operation;
        operation=OperationFactory.getInstance().createOperation("+");
        System.out.println(operation.getResult(1,1));
  }
}

不用我說輸出結(jié)果為2
這里我們利用java的多態(tài)性調(diào)用了OperationAdd 類的getResult方法傳入了1 和1
但是怎么創(chuàng)建的OperationAdd 我們并沒有去管。這就是簡單工廠的一個(gè)實(shí)例了
也許大家會(huì)認(rèn)為這么設(shè)計(jì)出來的計(jì)算器程序應(yīng)該很完美了吧,然而并不是。
沒有遵守開放—封閉原則。所謂的“開放-封閉”原則就是開放接口,封閉修改。如果將來需要添加一個(gè)開方的算法,那么,在簡單工廠模式中,就必須在簡單工廠類中添加相應(yīng)的判斷語句。前面說的必須也不是那么絕對(duì),這時(shí)我們再看工廠類中的makeOperation 方法 如果要加入一個(gè)開方的運(yùn)算類,我們不改工廠類的邏輯是可以通過newInstance調(diào)用這個(gè)新的開方運(yùn)算律但是 newInstance是弱類型。所以想完全的按照開放—封閉原則我們還是要來看一下工廠方法模式

優(yōu)點(diǎn)

簡單工廠顧名思義就是你只管調(diào)用操作不需要管創(chuàng)建類的過程所以叫簡單工廠(根據(jù)客戶端的選擇條件動(dòng)態(tài)實(shí)例化相關(guān)的類,對(duì)客戶端調(diào)用來說除去了與具體產(chǎn)品的依賴)因?yàn)閯?chuàng)建的邏輯交給了工廠類,相當(dāng)于就是給類的創(chuàng)建做了封裝。

缺點(diǎn)

簡單工廠沒有遵守開放—封閉原則。所謂的“開放-封閉”原則就是開放接口,封閉修改。如果將來需要添加一個(gè)開方的算法,那么,在簡單工廠模式中,就必須在簡單工廠類中添加相應(yīng)的case語句!

2. 工廠方法模式

晚上更新

3. 抽象工廠模式

晚上更新

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

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

  • 設(shè)計(jì)模式基本原則 開放-封閉原則(OCP),是說軟件實(shí)體(類、模塊、函數(shù)等等)應(yīng)該可以拓展,但是不可修改。開-閉原...
    西山薄涼閱讀 4,071評(píng)論 3 14
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法,類相關(guān)的語法,內(nèi)部類的語法,繼承相關(guān)的語法,異常的語法,線程的語...
    子非魚_t_閱讀 34,628評(píng)論 18 399
  • 1.接口基礎(chǔ)回顧 設(shè)計(jì)模式六大原則,其中依賴倒轉(zhuǎn)原則,強(qiáng)調(diào)我們應(yīng)該面向接口編程,那什么是接口?接口的作用? 接口如...
    孟婆湯不解渴閱讀 901評(píng)論 0 3
  • 該文章屬于劉小壯原創(chuàng),轉(zhuǎn)載請注明:劉小壯[http://www.itdecent.cn/u/2de707c93d...
    劉小壯閱讀 13,521評(píng)論 19 27
  • 在我們的身邊總有這樣一群人:看到別人經(jīng)過數(shù)年的努力,堅(jiān)持寫作,現(xiàn)在著書立傳,心里暗暗發(fā)誓:從明天開始我也堅(jiān)持寫作,...
    LH來慧閱讀 458評(píng)論 0 4

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