1.封装
效果最差, 功能全在一起,不易维护和单元测试
class OperatorTool {
class func calculate(_ num1: Double, _ operation: String, _ num2: Double) -> Double? {
switch operation {
case "+":
return num1 + num2
case "/":
assert(num2 != 0, "除数不能为零")
return num1 / num2
default:
return nil
}
}
}
// ==================使用==================
var operation = "+"; var num1: Double = 1;
OperatorTool.calculate(num1,operation,num2)
}
2.继承(协议)
功能分离,便于维护测试,但是多了个switch
protocol OperatorProtocol {
var num1: Double { get }
var num2: Double { get }
func calculate() -> Double
}
class Addition: OperatorProtocol {
var num1: Double
var num2: Double
init(_ num1: Double, _ num2: Double) {
self.num1 = num1
self.num2 = num2
}
func calculate() -> Double {
return num1 + num2
}
}
class Divide: OperatorProtocol {
var num1: Double
var num2: Double
init(_ num1: Double, _ num2: Double) {
self.num1 = num1
self.num2 = num2
}
func calculate() -> Double {
assert(num2 != 0, "除数不能为零")
return num1 / num2
}
}
// ==================使用==================
switch operation {
case "+":
let a = Addition(num1, num2)
a.calculate()
case "/":
let d = Divide(num1, num2)
d.calculate()
default:
break
}
3.多态
利用简单工厂模式, 解决了可恶的switch,但是暴露了OperatorProtocol和OperatorFactory两个类
class OperatorFactory {
class func createOperator(_ num1: Double, _ operation: String, _ num2: Double) -> OperatorProtocol? {
switch operation {
case "+":
return Addition(num1, num2)
case "/":
return Divide(num1, num2)
default:
return nil
}
}
}
// ==================使用==================
var o = OperatorFactory.createOperator(num1, operation, num2)
o?.calculate()
4.策略模式
使用者只需了解一个类 OperatorContext 就可以完成功能,松耦合
class OperatorContext {
private var anOperator: OperatorProtocol
init(_ anOperator: OperatorProtocol) {
self.anOperator = anOperator
}
convenience init?(_ num1: Double, _ operation: String, _ num2: Double) {
switch operation {
case "+":
self.init(Addition(num1, num2))
case "/":
self.init(Divide(num1, num2))
default:
return nil
}
}
// 建议用便利构造函数替代, 如上
class func createOperator(_ num1: Double, _ operation: String, _ num2: Double) -> OperatorContext? {
switch operation {
case "+":
return OperatorContext(Addition(num1, num2))
case "/":
return OperatorContext(Divide(num1, num2))
default:
return nil
}
}
func calculate() -> Double {
return anOperator.calculate()
}
}
// ==================使用==================
var context = OperatorContext(num1, operation, num2)
context?.calculate()