今天和大家分享一下設計模式中的 簡單工廠 工廠方法 抽象工廠
上圖是工廠模式百度百科的截圖,工廠模式(三種模式)的目的在于程序的可擴展性,便于維護,減少開發出錯,本人總結為工廠模式就是讓類的創建和使用分離,降低程序模塊之間的耦合程度(歡迎提出質疑)
1.簡單工廠模式(Simple Factory Pattern)
我這里來拿《大話設計模式》中“大鳥”指導“小菜”完成的一個簡單工廠來舉例子(編寫一個簡單的計算器程序),這里我把他的c#代碼換成了本人學習的java -- ps:本人也是剛畢業不久的菜鳥一枚,正在看這本書就當是寫個個人總結和大家分享一下。這本書評價不錯京東有正版有能力的朋友可以支持一下作者。也可以看網絡上的pdf.....
首先來分析一下計算器程序的目的是為了得到一個計算結果,我們應該抽象出這個結果首先我們是我們的抽象接口代碼
public interface Operation {
public double getResult(double number_a,double number_b);
}
Operation 接口中一個getResult 參數為 兩個double數。
假設目前只要滿足 + - * /的計算 好了我們來新建四個計算的運算類分別實現接口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("除數不能為零");
} catch (Exception e) {
e.printStackTrace();
}
}
result=number_a/number_b;
return result;
}
}
這里大家是不是萬事具備只欠東風了呢,問題來了具體的運算類怎么調用 何時調用誰呢,這時間我們把我們的重點工廠類請出來了,讓它決定我們怎么使用具體的運算類
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("請輸入正確的運算符");
} 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("沒有足夠權限,即不能訪問私有對象");
} catch (ClassNotFoundException e) {
System.out.println("類不存在");
e.printStackTrace();
} catch (ClassCastException e)
{
System.out.println("選擇的類不正確");
}
return operation;
}
}
我們先不管makeOperation方法先看createOperation方法。
createOperation只需要在調用的時間接受operator參數(+-*/)就能返回所對應的運算類了
下面是客戶端代碼
public class Main {
public static void main(String[] args) {
Operation operation;
operation=OperationFactory.getInstance().createOperation("+");
System.out.println(operation.getResult(1,1));
}
}
不用我說輸出結果為2
這里我們利用java的多態性調用了OperationAdd 類的getResult方法傳入了1 和1
但是怎么創建的OperationAdd 我們并沒有去管。這就是簡單工廠的一個實例了
也許大家會認為這么設計出來的計算器程序應該很完美了吧,然而并不是。
沒有遵守開放—封閉原則。所謂的“開放-封閉”原則就是開放接口,封閉修改。如果將來需要添加一個開方的算法,那么,在簡單工廠模式中,就必須在簡單工廠類中添加相應的判斷語句。前面說的必須也不是那么絕對,這時我們再看工廠類中的makeOperation 方法 如果要加入一個開方的運算類,我們不改工廠類的邏輯是可以通過newInstance調用這個新的開方運算律但是 newInstance是弱類型。所以想完全的按照開放—封閉原則我們還是要來看一下工廠方法模式
優點
簡單工廠顧名思義就是你只管調用操作不需要管創建類的過程所以叫簡單工廠(根據客戶端的選擇條件動態實例化相關的類,對客戶端調用來說除去了與具體產品的依賴)因為創建的邏輯交給了工廠類,相當于就是給類的創建做了封裝。
缺點
簡單工廠沒有遵守開放—封閉原則。所謂的“開放-封閉”原則就是開放接口,封閉修改。如果將來需要添加一個開方的算法,那么,在簡單工廠模式中,就必須在簡單工廠類中添加相應的case語句!
2. 工廠方法模式
晚上更新
3. 抽象工廠模式
晚上更新