Design Pattern(0) - decouple and factory mode
1. 計算簡單的 expression:
以下程式碼使用scala:
import Calculator.* import scala.io.StdIn.readLine object Main { @main def m(args: String*) = { println("Input number A:") val a = readLine.toFloat println("Input number B:") val b = readLine.toFloat println("Input an operator:") val op = readLine.strip try { val operation = Operation.createOperator(op) operation.a = a operation.b = b println(operation.getResult) } catch { case e:Exception => println(e) } } }
package Calculator abstract class Operation(var a: Float, var b: Float) { def getResult:Float } class OperationAdd(_a: Float = 0, _b: Float = 0) extends Operation(_a, _b) { override def getResult: Float = a + b } class OperationSub(_a: Float = 0, _b: Float = 0) extends Operation(_a, _b) { override def getResult: Float = a - b } class OperationMul(_a: Float = 0, _b: Float = 0) extends Operation(_a, _b) { override def getResult: Float = a * b } class OperationDiv(_a: Float = 0, _b: Float = 1) extends Operation(_a, _b) { require(b != 0) override def getResult: Float = a / b } object Operation { def createOperation(op: String): Operation = { op match { case "+" => new OperationAdd() case "-" => new OperationSub() case "*" => new OperationMul() case "/" => new OperationDiv() case _ => throw IllegalArgumentException("Illegal Operation") } } }
本篇主旨在於將程式碼解耦合。每個 OperationXXX 在程式中不互相影響,所以修復 Bug 或 Refactor 時不會影響其他元件的可用性。
子類別 _a 及 _b 是為了不遮蔽父類別的 var a 及 var b。
最後 createOperation 回傳各種 OperationXXX ,沒有正確初始化還是能呼叫 getResult 其實風險。
2. 匿名物件工廠模式:
透過滿足 trait 讓物件具有特定行為,再利用工廠產生匿名物件。
package Calculator object Operation { def createOperation(op: String): MathOperation = { op match { case "+" => (_: Float) + (_: Float) case "-" => (_: Float) - (_: Float) case "*" => (_: Float) * (_: Float) case "/" => (_: Float) / (_: Float) } } } trait MathOperation { def getResult(a: Float, b:Float): Float }
物件生成的細節封裝在 createOperation,運算的操作封裝在 getResult。使用時透過 createOperation 和 getResult 接口進行操作。
import Calculator.Operation.createOperation import Cash.* object Main { @main def m(args: String*) = { val operationAdd = createOperation("+") println(operationAdd.getResult(10, 20)) val operationSub = createOperation("-") println(operationSub.getResult(10, 20)) } }
Reference:
1. 大話設計模式-程杰
留言
張貼留言