實現一個簡單計算器代碼(加減乘除)設計模式
/** * 運算類 * Created by callmeDevil on 2019/5/26. */ public class Operation { /** * 獲取運算結果 * @param numA 數值A * @param numB 數值B * @param operate 運算符 * @return */ public static double getResult(double numA, double numB, String operate) { double result = 0L; switch (operate) { case "+": result = numA + numB; break; case "-": result = numA - numB; break; case "*": result = numA * numB; break; case "/": result = numA / numB; break; default: break; } return result; } }
/** * 測試類 * Created by callmeDevil on 2019/5/26. */ public class Test { public static void main(String[] args) { Operation operation = new Operation(); double numA = 10; double numB = 2; System.out.println("加法:" + operation.getResult(numA, numB, "+")); System.out.println("減法:" + operation.getResult(numA, numB, "-")); System.out.println("乘法:" + operation.getResult(numA, numB, "*")); System.out.println("除法:" + operation.getResult(numA, numB, "/")); } }
可是這樣就有個問題,若是這個計算器還須要實現開根號運算呢?難道就直接在Operation類添加一個switch分支就好了嗎?不是的,這樣會讓原來良好運行的代碼產生變化,風險太大,所以須要將各類運算的邏輯分離開來,此處引入簡單工廠模式。ide
又稱爲靜態工廠模式,根據工廠類傳入的參數動態決定建立某種類(這些類都繼承自同一父類或實現同一接口)的實例。測試
/** * 運算基礎類 * Created by callmeDevil on 2019/5/26. */ public class BaseOperation { private double numA; private double numB; // 此處省略get、set方法 /** * 獲取結果 * @return */ public double getResult() { double result = 0L; return result; } }
/** * 加法運算 * Created by callmeDevil on 2019/5/26. */ public class OperationAdd extends BaseOperation { @Override public double getResult() { return getNumA() + getNumB(); } }
/** * 減法運算 * Created by callmeDevil on 2019/5/26. */ public class OperationSub extends BaseOperation { @Override public double getResult() { return getNumA() - getNumB(); } }
/** * 乘法運算 * Created by callmeDevil on 2019/5/26. */ public class OperationMul extends BaseOperation { @Override public double getResult() { return getNumA() * getNumB(); } }
/** * 除法運算 * Created by callmeDevil on 2019/5/26. */ public class OperationDiv extends BaseOperation { @Override public double getResult() { if (getNumB() == 0){ throw new RuntimeException("除數不能爲0!"); } return getNumA() / getNumB(); } }
/** * 測試類 * Created by callmeDevil on 2019/5/26. */ public class Test { public static void main(String[] args) { // 實現其餘運算只須要更改輸入的運算符便可 BaseOperation operation = OperationFactory.createOperation("+"); operation.setNumA(10); operation.setNumB(2); System.out.println("加法:" + operation.getResult()); } }
將每種運算的具體實現分離在不一樣的類中,工廠類只須要負責根據輸入的運算符來建立對應的運算類實例便可。好比要一個開方運算是吧,那麼須要建立一個開方運算類,一樣繼承BaseOperation,接着在工廠類中switch中添加一個case分支,而後客戶端便可以跟其餘運算同樣調用。
可能有人會問,這裏不也一樣是修改了switch分支條件嗎?有什麼區別?問得好,說明有思考過,可是緣由也很明顯,要仔細想一想。把四種基礎運算具體實現分離出去,工廠類中就包含了四行建立實例的代碼,這時修改了switch分支的風險,和普通實現方式的風險相比,哪一個大已經不用細說了吧。編碼
這裏案例代碼比較簡單,因此看起來會很是明朗,想必沒必要多說讀者應該也能稍有體會。假如每一個類型的運算很是複雜,甚至與其餘模塊關聯,那使用設計模式的好處就體現出來了,比起所有代碼堆在一個switch case上,在單獨的一個類裏面會更好維護和擴展吧?想作到徹底不修改switch的代碼是不可能,最重要的是咱們達到了鬆耦合、可複用、可擴展目的,同時還下降了風險,有何不可。設計