設計思想學習—工廠方法模式

簡單工廠模式

主要內容

  • 簡單工廠模式
  • 工廠方法模式

首先先來一個沒有運用模式的普通案例
模擬計算器例子

public class Calc{
    public static void main(String[] args){
        Scanner sca=new Scanner(System.in);
        System.out.println("請輸入第一個數字");
        String numA=sca.nextLine();
        System.out.println("請輸入算數符號");
        String symbol=sca.nextLine();
        System.out.println("請輸入第二個數字");
        String numB=sca.nextLine();
        double amount=0.0;
        double first=Double.valueOf(numA);
        double second=Double.valueOf(numB);
        switch (symbol) {
        case "+":
            amount=first+second;
            break;
        case "-":
            amount=first-second;        
            break;
        case "*":
            amount=first*second;
            break;
        case "/":
            amount=first/second;
            break;
        }
        System.out.println(amount);
    }
}

簡單工廠版

class Operation{
    public double getResult(){return 0.0;}
}
class Add extends Operation{
    public double getResult(double numA,double numB){
        return numA+numB;
    }
}
class Sub extends Operation{
    public double getResult(double numA,double numB){
        return numA-numB;
    }
}
class Mul extends Operation{
    public double getResult(double numA,double numB){
        return numA*numB;
    }
}
class Div extends Operation{
    public double getResult(double numA,double numB){
        return numA/numB;
    }
}
class OperationFactory{
    public Operation produce(String symbol){
        Operation operation=null;
        switch (symbol) {
        case "+":
            operation=new Add();
            break;
        case "-":
            operation=new Sub();
            break;
        case "*":
            operation=new Mul();
            break;
        case "/":
            operation=new Div();
            break;
        }
        return operation;
    }
}
public class Calc{
    public static void main(String[] args){
        Scanner sca=new Scanner(System.in);
        System.out.println("請輸入第一個數字");
        String numA=sca.nextLine();
        System.out.println("請輸入算數符號");
        String symbol=sca.nextLine();
        System.out.println("請輸入第二個數字");
        String numB=sca.nextLine();
        double amount=0.0;
        double first=Double.valueOf(numA);
        double second=Double.valueOf(numB);
        OperationFactory factory=new OperationFactory();
        Operation operation=factory.produce(symbol);
        amount=operation.getResult(first,second);
        System.out.println(amount);
    }
}

好處很顯而易見了,簡單工廠方法明確了各自的職責和權利,對於客戶端來說不用在與具體的產品產生依賴關係。但是這裏卻違反了開閉原則,如果想要加入新的運算方法只能修改工廠方法,那麼就引申出了GOF23種設計模式之一的工廠方法模式,首先來看下GOF和23種設計模式

GOF的23中設計模式

圖片爲轉載

GoF
“四人幫”,又稱Gang of Four,即Erich Gamma, Richard Helm, Ralph Johnson & John Vlissides

創建型模式(5個):單例模式、原型模式、建造者模式、工廠模式、抽象工廠模式。

結構型模式(7個):橋接模式、外觀模式、組合模式、裝飾模式、適配器模式、代理模式、享元模式。

行爲型模式(11個):迭代器模式、解釋器模式、觀察者模式、中介者模式、訪問者模式、備忘錄模式、狀態模式、策略模式、模版方法模、命令模式、職責鏈模式式。

現在我們來回歸工廠方法模式

工廠方法模式

先來看看實現了開閉原則的工廠模式代碼

interface Factory{
    Operation creatOperation();
}
class AddFactory implements Factory{
    public Operation creatOperation(){
        return new Add();
    }
}
class SubFactory implements Factory{
    public Operation creatOperation(){
        return new Sub();
    }
}
class MulFactory implements Factory{
    public Operation creatOperation(){
        return new Mul();
    }
}
class DivFactory implements Factory{
    public Operation creatOperation(){
        return new Div();
    }
}
public class Calc{
    public static void main(String[] args){
        Scanner sca=new Scanner(System.in);
        System.out.println("請輸入第一個數字");
        String numA=sca.nextLine();
        System.out.println("請輸入算數符號");
        String symbol=sca.nextLine();
        System.out.println("請輸入第二個數字");
        String numB=sca.nextLine();
        double amount=0.0;
        double first=Double.valueOf(numA);
        double second=Double.valueOf(numB);
        Factory factory=null;
        //這裏注意的是我們又把判斷邏輯放在客戶端這很不好
        //這個缺點先掛起,學習策略模式的時候一起解決
        switch (symbol) {
        case "+":
            factory=new AddFactory();
            break;
        case "-":
            factory=new SubFactory();
            break;
        case "*":
            factory=new MulFactory();
            break;
        case "/":
            factory=new DivFactory();
            break;
        }
        Operation operation=factory.creatOperation();
        amount=operation.getResult(first,second);
        System.out.println(amount);
    }
}

如果想要增加平方的方法就只有寫一個平方類繼承運算類,在寫一個平方工廠實現工廠方法,然後客戶端選擇調用即可,而不用像簡單工廠一樣還要去加一個case

下面是簡單工廠和工廠方法uml導圖摘自《大話設計模式》
簡單工廠
不符合開閉原則
工廠方法
只用增加相映的工廠和類

剛開始接觸的時候我看了很多博客和書,卻只是感覺到越來越複雜和麻煩,完全沒有感受到這些方法帶來的好處。畢竟紙上談兵你是理解不了現實打戰的種種,就像站在岸上學不會游泳一樣。
但隨着我一遍又一遍的嘗試和自己項目經驗的結合,然後回來研究拜讀,發現又有不一樣的收穫,越看越能發現它的博大精深和迷人之處。
博客獻給自己以及和我一樣的小菜鳥,希望我們能在技術的道路上走得更遠、更穩。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章