系列文章目錄
文章目錄
- 系列文章目錄
- 需要了解工廠制造細節嗎?
- 簡單工廠模式實現
- 工廠方法模式的實現
- 簡單方法? 工廠方法?
- 總結
需要了解工廠制造細節嗎?
我們在前面的文章中為大家介紹了簡單工廠模式,我們知道 簡單工廠模式是最基本的創建實例相關的設計模式, 但是在真實情況中,有更多復雜的情況需要處理。簡單工廠生成實例的類,知道了太多的細節,這就導致這個類很容易出現難維護、靈活性差的問題。
現實中我們要想過好生活,是不太需要也不太可能知道所有細節的。比如說,我們知道豬長什么樣子,也知道紅燒肉很好吃,但一頭豬是通過怎么樣的過程變成紅燒肉的呢?我們并不需要關注。所以如果將來能生產出這樣一臺機器,送進去的是豬,出來的就是紅燒肉,貌似就好多了。
在我們的程序中,確實存在封裝實例創建過程的模式----工廠方法模式,這個模式可以讓創建實例的過程封裝到工廠類中, 避免耦合,它與簡單工廠模式是一個體系的。
簡單工廠模式實現
下面我們以簡單工廠模式的計算器為例,工廠類和客戶端代碼如下:
public class OperationFactory{public static Operation createOperate(String operate){Operation oper = null;switch(operate){case "+":oper = new Add();break;case "-":oper = new Sub();break;case "*":oper = new Mul();break;case "/":oper = new Div();break;}return oper;}}public static void main(String[] args) {Operation oper = OperationFactory.createOperate(strOperate);double result = oper.getResult(numberA,numberB);}
工廠方法模式的實現
如果換成工廠方法模式寫這個計算器,代碼如下:
public interface IFactory{public Operation createOperation();}public class AddFactory implements IFactory{@Overridepublic Operation createOperation() {return new Add();}} public class SubFactory implements IFactory{@Overridepublic Operation createOperation() {return new Sub();}}public class MulFactory implements IFactory{@Overridepublic Operation createOperation() {return new Mul();}}public class DivFactory implements IFactory{@Overridepublic Operation createOperation() {return new Div();}}//此時我們的OperationFactory類代碼public class OperationFactory{public static Operation createOperation(String operate){IFactory factory = null;Operation oper = null;switch(operate){case "+":factory = new AddFactory();break;case "-":factory = new SubFactory();break;case "*":factory = new MulFactory();break;case "/":factory = new DivFactory();break;}oper = factory.createOperation();return oper;}}
簡單方法? 工廠方法?
以前我們說過,如果我們現在需要增加其他運算,比如求x的n次方,或者求以a為底b的對數,這些功能的增加哎,在簡單工廠里,我們是先去加求x的n次方運算指數類,然后去更改OperationFactory類,當中加Case語句分支判斷即可,現在用了工廠方法,加指數運算沒問題,去改OperationFactory類的分支也沒問題,但又增加了一個指數工廠類,這不等于不但沒有降低難度,反而增加類,把復雜性增加了嗎?
簡單工廠模式的最大優點在于工廠類中包含必要的邏輯判斷,根據客戶端的選擇條件動態的實例化相關的類,對于客戶端來說,去除了與具體產品的依賴。 就像計算器這個實例,讓客戶端不用管應該用哪個類的實例,只需要把“+”給工廠,工廠就自動的給出了相應的實例,客戶端只需要去運算就可以了。但是我們要增加一個X的n次方的操作的話,我們需要給OperationFactory類的方法里加Case條件,這就是說,我們不但對擴展開放了,對修改也開放了,這違背了開放-封閉原則。 也就是說這個OperationFactory類承載了太多功能。
但是在我們上述的工廠方法中好像也沒有做到這一點,他比原來多出了四個運算工廠類和一個工廠接口,其實是因為我們上述代碼并沒有體現工廠模式的優點,舉個例子:我們公司原來只有一家工廠,生產四種不同的產品。后來發展比較好,需要增加兩種產品放在另一個地方開設新的工廠,新的工廠不應該影響原來工廠的運作。這樣我們只需總公司那里再增加一下協調管理部門就好了。
就編程而言,我們應該盡量將長的代碼分派切割成小段,再將每一小段‘封裝’起來,減少每段代碼之間的耦合,這樣風險就分散了,需要修改或擴展的難度就降低了。 加減乘除四個類算是一個工廠的產品,不妨叫他們(基礎運算工廠)類,現在增加指數、對數運算類,如果算是另一種工廠的兩種產品,不妨稱他們為‘高級運算工廠’類,就沒必要去影響原有的基礎運算工廠運作了。
代碼實現:
public class Pow extends Operation {public double getResult(double numberA,double numberB){return Math.pow(numberA,numberB);}
}public class Log extends Operation{public double getResult(double numberA,double numberB){return Math.log(numberB)/Math.log(numberA);}
}
public interface IFactory {public Operation createOperation();
}
//基礎運算工廠類
public class basicFactory implements IFactory{public Operation createOperation(String operate) {IFactory factory = null;Operation oper = null;switch(operate){case "+" :factory = new AddFactory();break;case "-":factory = new SubFactory();break;case "*":factory = new MulFactory();break;case "/" :factory = new DivFactory();break;}oper = factory.createOperation();return oper;}
}
//高級運算工廠類
public class AdvancedOperationFactory implements IFactory{@Overridepublic Operation createOperation(String operType) {Operation oper = null;switch(operType){case "pow":oper = new Pow();break;case "log":oper = new Log();break;}return oper;}
}public class OperationFactory {public static Operation createOperate(String strOperate) {Operation oper = null;IFactory factory = null;switch (strOperate) {case "+":case "-":case "*":case "/":factory = new basicFactory();break;case "pow":case "log":factory = new AdvancedOperationFactory();break;}oper = factory.createOperation();return oper;}
}
這里我們新的OperationFactory類已經不存在運算子類實例化的代碼了,也就是說,在這個代碼里,全部都是借口與具體工廠類,并不存在具體的實現,與原來的OperationFactory類對比實例化的過程延遲到了工廠子類中。這里也是依賴倒轉原則中的針對接口編程,不要針對實現編程。 注意到關鍵詞 – 延遲到子類
工廠方法模式,定義一個用于創建對象的接口,讓子類決定實例化哪一個類,工廠方法使一個類IDE實例化延遲到其子類 。
工廠方法克服了簡單工廠違背開放-封閉原則的缺點,同樣保持了封裝對象創建過程的優點。工廠方法模式是簡單工廠模式的進一步抽象和推廣。 由于使用了多態性,工廠方法模式保持了簡單工廠模式的優點克服了他的缺點。另外工廠方法模式本質就是對獲取對象過程的抽象。
工廠模式好處:
- 對于復雜的參數構造對象,可以很好的對外層屏蔽代碼的復雜性,注意這里是指創建實例的構造對象。
- 工廠方法模式有很好的解耦能力,這就是針對接口在編程,當我們要修改具體實現層的代碼時,上層代碼完全不了解實現層的情況,因此不會影響到上層代碼的調用。達到解耦目的。
總結
以上就是本文全部內容,本文主要向大家介紹了設計模式中的工廠模式,通過對計算器簡單工廠模式代碼的修改擴展,一步一步引出工廠方法模式的代碼,介紹工廠方法模式的優點和適用性。感謝各位能夠看到最后,如有問題,歡迎各位大佬在評論區指正,希望大家可以有所收獲!創作不易,希望大家多多支持!