標籤:ror new log null 執行個體化 turn class private exce
我以計算機為例寫一個簡單原廠模式,只完成加減乘除4個計算功能,考慮到其他功能方便日後擴充,遵循開放-封閉原則。
先看一下C#的簡單工廠是如何?的:
定義抽象類別Operation,加減乘除的實現由子類派生,最後由OperationFactory決定執行個體化哪一個子類。
namespace OperationLibrary{ public abstract class Operation { private int num_A = 0; public int Num_A { get { return num_A; } set { num_A = value; } } private int num_B = 0; public int Num_B { get { return num_B; } set { num_B = value; } } public abstract double getResult(); } public class OperationAdd : Operation { public override double getResult() { return Num_A + Num_B; } } public class OperationSub : Operation { public override double getResult() { return Num_A - Num_B; } } public class OperationMul : Operation { public override double getResult() { return Num_A * Num_B; } } public class OperationDiv : Operation { public override double getResult() { if (Num_B == 0) throw new Exception("除數不能為0"); return Num_A / Num_B; } } public class OperationFactory { public static Operation createOperate(string operate) { Operation oper = null; switch (operate) { case "+": oper = new OperationAdd(); break; case "-": oper = new OperationSub(); break; case "*": oper = new OperationMul(); break; case "/": oper = new OperationDiv(); break; } return oper; } }}
用戶端調用:
Operation oper = OperationFactory.createOperate("/");oper.Num_A = 6;oper.Num_B = 2;oper.getResult(); //3
js類比C#的簡單工廠:
var Operation = function(){ this.num_A = this.num_B = 0; }; var OperationAdd = function(){}; OperationAdd.prototype = new Operation(); OperationAdd.prototype.getResult = function(){ return this.num_A + this.num_B; }; var OperationSub = function(){}; OperationSub.prototype = new Operation(); OperationSub.prototype.getResult = function(){ return this.num_A - this.num_B; }; var OperationMul = function(){}; OperationMul.prototype = new Operation(); OperationMul.prototype.getResult = function(){ return this.num_A * this.num_B; }; var OperationDiv = function(){}; OperationDiv.prototype = new Operation(); OperationDiv.prototype.getResult = function(){ if(this.num_B == 0) throw new Error(‘除數不能為0‘); return this.num_A / this.num_B; }; var OperateFactory = function(){}; OperateFactory.createOperate = function(operate){ var oper; switch(operate){ case "+": oper = new OperationAdd(); break; case "-": oper = new OperationSub(); break; case "*": oper = new OperationMul(); break; case "/": oper = new OperationDiv(); break; } return oper; }; //調用: var oper = OperateFactory.createOperate(‘+‘); oper.num_A = 1; oper.num_B = 2; alert(oper.getResult()); //3
js完全照搬C#的模式顯然太複雜,根據js語言的特性實現一個:
var Operation = function(){ this.num_A = this.num_B = 0; }; Operation.prototype.OperationAdd = function(){ return this.num_A + this.num_B; }; Operation.prototype.OperationSub = function(){ return this.num_A - this.num_B; }; Operation.prototype.OperationMul = function(){ return this.num_A * this.num_B; }; Operation.prototype.OperationDiv = function(){ if(this.num_B == 0) throw new Error(‘除數不能為0‘); return this.num_A / this.num_B; };
//策略 var operateStrategy = { ‘+‘:‘OperationAdd‘, ‘-‘:‘OperationSub‘, ‘*‘:‘OperationMul‘, ‘/‘:‘OperationDiv‘ }; //工廠 var OperateFactory = (function(){ var oper; return function(operate){ //只執行個體化一次 oper = oper || new Operation(); return { setNumber:function(a,b){ oper.num_A = a; oper.num_B = b; }, getResult:function(){ var fName = operateStrategy[operate], fun = oper[fName] || function(){}; return fun.call(oper); } }; }; })(); //調用: var oper = OperateFactory(‘+‘); oper.setNumber(1,3); alert(oper.getResult()); oper = OperateFactory(‘*‘); oper.setNumber(2,3); alert(oper.getResult());
總結:如果日後需要擴充計算機的功能,我們需要維護2個地方,一個是為Operation的原型添加所需要的新功能,另一個是維護策略對象:operateStrategy, 基本上不需要修改程式的內部方法,而是為它增加擴充,基本符合開放-封閉原則。
js簡單工廠