設計模式學習總結——工廠方法模式
今天來講述一下關於工廠方法模式的問題,以及使用的地方。
關於工廠方法模式的介紹如下:
工廠方法(Factory Method)模式,定義一個創建產品對象的工廠接口,將實際創建工作推遲到子類當中。核心工廠類不再負責產品的創建,這樣核心類成爲一個抽象工廠角色,僅負責具體工廠子類必須實現的接口,這樣進一步抽象化的好處是使得工廠方法模式可以使系統在不修改具體工廠角色的情況下引進新的產品。
上面這句話,怎麼理解呢?
很好理解,我們都知道,簡單工廠模式,違背了一個原則,就是我們著名的開放-封閉原則,也就是說,簡單工廠模式,是擴展進行了開放,但是也對修改進行了開放。
按照上一篇我們所講述的簡單工廠模式的計算器來舉例:
實現步驟如下:
1.創建一個操作類,用來保存,對應數字,以及得到最終結果:
/**
* 具體的操作類
* */
public class Operate {
public double numberA;
public double numberB;
public double getResult() throws Exception {
double resultNumber = 0d;
return resultNumber;
}
}
具體的加減乘除對應的操作類:
public class OperateAdd extends Operate {
@Override
public double getResult() throws Exception {
double result = 0d;
result = numberA + numberB;
return result;
}
}
public class OperateSub extends Operate {
@Override
public double getResult() throws Exception {
double result = 0d;
result = numberA - numberB;
return result;
}
}
public class OperateMul extends Operate {
@Override
public double getResult() throws Exception {
double result = 0d;
result = numberA * numberB;
return result;
}
}
public class OperateDiv extends Operate {
@Override
public double getResult() throws Exception {
double result = 0d;
if (numberB != 0) {
result = numberA / numberB;
} else {
throw new Exception("除數不能爲0");
}
return result;
}
}
簡單工廠類:
public class OperateFactory {
/**
* 讓工廠知道使用哪一個對象。
* @param strOperate
* @return
*/
public static Operate createOperate(String strOperate){
Operate operate = null;
switch (strOperate){
case "+":
operate = new OperateAdd();
break;
case "-":
operate = new OperateSub();
break;
case "*":
operate = new OperateMul();
break;
case "/":
operate = new OperateDiv();
break;
}
return operate;
}
}
客戶端類:
public class Calc {
public static void main(String[] args) throws Exception {
Operate operate = null;
operate = OperateFactory.createOperate("+");
operate.numberA = 1;
operate.numberB = 1;
double result = operate.getResult();
System.out.println("最終結果如下:"+result);
}
}
上面這段代碼的實現就是簡單工廠對於計算器的實現,如果我們這時有一個新的需求:要求加一個求M數的N次方,我們是一定需要在簡單工廠類的switch中增加新的case分支。相當於我們已經提供了對於簡單工廠類的修改功能,那麼就違背了開放擴展-封閉修改的原則了。所以,這個時候,工廠方法模式就來了。
工廠方法模式,很好理解,就是定義一個基本工廠接口,然後創建一個工廠繼承這個接口,然後通過新的工廠去創建你所需要的類。完了。。。
拿上面的計算器來舉例:
1.首先定義一個基本工廠:
public interface MyFactory {
public Operate createFactory();
}
2.定義你所需要的加法,減法,乘法,除法的工廠,這幾個工廠都實現了基本工廠接口。
public class FactoryAdd implements MyFactory {
@Override
public Operate createFactory() {
return new OperateAdd();
}
}
public class FactorySub implements MyFactory{
@Override
public Operate createFactory() {
return new OperateSub();
}
}
public class FactoryMul implements MyFactory {
@Override
public Operate createFactory() {
return new OperateMul();
}
}
public class FactoryDiv implements MyFactory {
@Override
public Operate createFactory() {
return new OperateDiv();
}
}
3.客戶端類:
public class TestMain {
public static void main(String[] args) throws Exception {
//
MyFactory myFactory = new FactoryAdd();
Operate operate = myFactory.createFactory();
operate.numberA = 1;
operate.numberB = 2;
System.out.println("我是結果:"+operate.getResult());
}
}
輸出結果:
我是結果:3.0
類比於簡單工廠模式:
相同點:
- 都是集中封裝了對象的創建,使得需要更換對象的時候,不需要做很大的改動就可以實現。
- 降低了客戶程序與產品對象的耦合。
不同點:
- 工廠方法模式是簡單工廠模式的進一步抽象和推廣,由於使用了多態性,工廠方法模式,保存了簡單工廠模式的優點:開放拓展性。克服了它的缺點:開放了修改性。
缺點:
- 工廠方法模式,在增加每一個產品,就必須增加一個產品工廠的類,增加了額外的開發量。
至此,工廠方法模式總結完畢,後面LZ會使用反射對工廠方法模式的缺點進行優化。。。。