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. 大話設計模式-程杰
留言
張貼留言