Factory Pattern 工廠模式

一.簡介

將簡單工廠模式用switch case選擇需要的子類別實體改為選擇用哪種子類別的工廠創造實體,解決簡單工廠模式違反開放-封閉原則的缺點,擴充功能時只需要新增子類別及產生該子類別的工廠。

二.工廠模式的組成

1.利用多型的子類別
2.可產生該子類別的工廠類別

三.實作


enum OperationError:Error {
    case div0Problem
}
class Operation{//父類別
    var num:Double?;
    private var _num1:Double = 0.0;
    private var _num2:Double = 0.0;
    var num1:Double{
        set(original){
            self._num1 = original;
        }
        get{
            return self._num1;
        }
    }
    var num2:Double{
        set(original){
            self._num2 = original;
        }
        get{
            return self._num2;
        }
    }
    func  operation()throws->Double{return 0.0};
}
class OperationAdd: Operation {//子類別-加法運算
    override func operation()->Double {
        return num1+num2;
    }
}
class OperationSub: Operation {//子類別-減法運算
    override func operation() -> Double {
        return num1-num2;
    }
}
class OperationMul: Operation {//子類別-乘法運算
    override func operation() -> Double {
        return num1*num2;
    }
}
class OperationDiv:Operation{//子類別-除法運算
    override func operation()throws -> Double {
        if(num2==0){
            throw OperationError.div0Problem;
        }
        return num1/num2;
    }
    func test()throws{
        try operation();
    }
}
protocol OperationFactory {//工廠協議
    func createOperation() -> Operation;
}
class OperationAddFactory : OperationFactory{//產生加法運算子類別的工廠
    func createOperation() -> Operation {
        return OperationAdd();
    }
}
class OperationSubFactory : OperationFactory{//產生減法運算子類別的工廠
    func createOperation() -> Operation {
        return OperationSub();
    }
}
class OperationMulFactory : OperationFactory{//產生乘法運算子類別的工廠
    func createOperation() -> Operation {
        return OperationMul();
    }
}
class OperationDivFactory : OperationFactory{//產生除法運算子類別的工廠
    func createOperation() -> Operation {
        return OperationDiv();
    }
}
var operationFactory:OperationFactory?;
operationFactory = OperationSubFactory();//選擇加法運算
var operation:Operation?;
operation = operationFactory?.createOperation();
operation?.num1 = 19.2;
operation?.num2 = 21;
do{
    var result:Double?;
    result = try operation?.operation();
    print(result!);
}
catch{
    print("發生例外")
}
operation?.num ?? 0.0;