第一章 Caché 設(shè)計(jì)模式 簡單工廠模式
定義
- 簡單工廠模式屬于創(chuàng)建型模式筏餐,又可稱為靜態(tài)工廠模式返顺,這是由一個(gè)工廠對(duì)象決定創(chuàng)建出哪一種產(chǎn)品類的實(shí)例荞彼。
使用場景
- 工廠類負(fù)責(zé)創(chuàng)建的對(duì)象比較少。
- 客戶只需知道傳入工廠類的參數(shù)惧盹,而無須關(guān)心創(chuàng)建對(duì)象的邏輯乳幸。
優(yōu)點(diǎn)
- 使用戶根據(jù)參數(shù)獲得對(duì)一個(gè)的類實(shí)例,避免了直接實(shí)例化類型钧椰,降低了耦合性粹断。
- 能把客戶類和具體子類的實(shí)現(xiàn)解耦,客戶類不再需要知道有哪些子類以及應(yīng)當(dāng)實(shí)例化哪個(gè)子類:客戶類往往有多個(gè)嫡霞,如果不使用簡單工廠瓶埋,那么所有的客戶類都要知道所有子類的細(xì)節(jié)。而且一旦子類發(fā)生改變秒际,所有的客戶類都要進(jìn)行修改悬赏。
缺點(diǎn)
- 可實(shí)例化的類型在編譯期間已經(jīng)被確定。
- 如果增加新類型娄徊,則需要修改工廠,這違背了開放封閉原則盾戴。
- 子類多過不適合使用寄锐。
示例
- 用Caché 實(shí)現(xiàn)一個(gè)計(jì)算器控制臺(tái)程序,要求輸入兩個(gè)數(shù)和運(yùn)算符號(hào)尖啡。
可能會(huì)寫成這樣:
/// w ##class(PHA.YX.Design.Program).GetResult()
ClassMethod GetResult()
{
READ "輸入第一個(gè)數(shù)字:", numberA,!
READ "輸入操作符:", operate,!
READ "輸入第二個(gè)數(shù)字:", numberB,!
s result = ""
i operate = "+" d
.s result = numberA + numberB
i operate = "-" d
.s result = numberA - numberB
i operate = "*" d
.s result = numberA * numberB
i operate = "/" d
.s result = numberA / numberB
q result
}
缺點(diǎn):
- if表達(dá)式每次都需要判斷橄仆,等于計(jì)算機(jī)做了三次無用功。
- 如果除法衅斩,輸入了0盆顾,除法會(huì)報(bào)錯(cuò)。
DHC-APP> w ##class(PHA.YX.Design.Program).GetResult()
輸入第一個(gè)數(shù)字:1
輸入操作符:/
輸入第二個(gè)數(shù)字:1.5
.6666666666666666667
DHC-APP> w ##class(PHA.YX.Design.Program).GetResult()
輸入第一個(gè)數(shù)字:1
輸入操作符:/
輸入第二個(gè)數(shù)字:0
.s result = numberA / numberB
^
<DIVIDE>zGetResult+12^PHA.YX.Design.Program.1
- 如果改成swtich($case)
可能會(huì)寫成這樣:
/// w ##class(PHA.YX.Design.Program).GetResultCase()
ClassMethod GetResultCase()
{
READ "輸入第一個(gè)數(shù)字:", numberA,!
READ "輸入操作符:", operate,!
READ "輸入第二個(gè)數(shù)字:", numberB,!
s result= $case(operate,
"+" : numberA + numberB,
"-" : numberA + numberB,
"*" : numberA + numberB,
"/" : numberA + numberB)
q result
}
缺點(diǎn):
- 如果加減乘除方法非常大畏梆,每次修改其中一個(gè)都會(huì)編譯其他三個(gè)運(yùn)算方法您宪。
- 增加錯(cuò)誤修改,可能日后修改代碼修改錯(cuò)奠涌。
結(jié)構(gòu)圖
image.png
完整示例
- 利用面相對(duì)象的繼承和多態(tài)宪巨。
- 增加一個(gè)冪次運(yùn)算。
- 由此例子舉一反三溜畅。
- 改修運(yùn)算捏卓,只需要去對(duì)應(yīng)的類去修改就好了。只編譯對(duì)應(yīng)的類慈格。
注意
- Operation類的numberA怠晴,numberB為私有字段屬性,其他類無法調(diào)用浴捆。InitialExpression設(shè)置初始值蒜田。
- Operation類的numberA,numberB字段汤功,Get物邑,Set方法中的屬性,要用i%property,否則報(bào)出遞歸錯(cuò)誤。
- Operation類GetResult()為抽象方法色解,子類需要重新實(shí)現(xiàn)茂嗓。
- Program類SimpleFactory()方法,要顯示生命oper類型,否則無法用“.”語法科阎。
- OperationFactory類返回的是Operation類對(duì)象述吸,這里及是多態(tài)。
- 其他操作類均為繼承類Operation類的子類锣笨,重寫Operation類GetResult()方法蝌矛。
調(diào)用
Class PHA.YX.Design.Program Extends %RegisteredObject
{
/// w ##class(PHA.YX.Design.Program).SimpleFactory()
ClassMethod SimpleFactory()
{
READ "輸入第一個(gè)數(shù)字:", numberA,!
READ "輸入操作符:", operate,!
READ "輸入第二個(gè)數(shù)字:", numberB,!
# dim oper as PHA.YX.Design.SimpleFactory.Operation
s oper = ##class(PHA.YX.Design.SimpleFactory.OperationFactory).CreateOperate(operate)
d oper.numberASet(numberA)
d oper.numberBSet(numberB)
s result = oper.GetResult()
q result
}
}
輸出
DHC-APP>w ##class(PHA.YX.Design.Program).SimpleFactory()
輸入第一個(gè)數(shù)字:1
輸入操作符:+
輸入第二個(gè)數(shù)字:1
2
DHC-APP>w ##class(PHA.YX.Design.Program).SimpleFactory()
輸入第一個(gè)數(shù)字:2
輸入操作符:-
輸入第二個(gè)數(shù)字:3
-1
DHC-APP>w ##class(PHA.YX.Design.Program).SimpleFactory()
輸入第一個(gè)數(shù)字:6
輸入操作符:*
輸入第二個(gè)數(shù)字:3
18
DHC-APP>w ##class(PHA.YX.Design.Program).SimpleFactory()
輸入第一個(gè)數(shù)字:1
輸入操作符:/
輸入第二個(gè)數(shù)字:1.5
0.6666666666666666667
DHC-APP>w ##class(PHA.YX.Design.Program).SimpleFactory()
輸入第一個(gè)數(shù)字:1
輸入操作符:/
輸入第二個(gè)數(shù)字:0
除數(shù)不能為0。
DHC-APP>w ##class(PHA.YX.Design.Program).SimpleFactory()
輸入第一個(gè)數(shù)字:3
輸入操作符:**
輸入第二個(gè)數(shù)字:3
27
工廠類
Class PHA.YX.Design.SimpleFactory.OperationFactory Extends %RegisteredObject
{
ClassMethod CreateOperate(operate As %String) As Operation
{
# dim oper as PHA.YX.Design.SimpleFactory.Operation
s oper = $case(operate,
"+" : ##class(PHA.YX.Design.SimpleFactory.OperationAdd).%New(),
"-" : ##class(PHA.YX.Design.SimpleFactory.OperationSub).%New(),
"*" : ##class(PHA.YX.Design.SimpleFactory.OperationMul).%New(),
"/" : ##class(PHA.YX.Design.SimpleFactory.OperationDiv).%New(),
"**" : ##class(PHA.YX.Design.SimpleFactory.OperationIndex).%New())
q oper
}
}
運(yùn)算類
Class PHA.YX.Design.SimpleFactory.Operation Extends %RegisteredObject
{
Property numberA As %Decimal [ InitialExpression = 0, Private ];
Method numberAGet() As %String [ ServerOnly = 1 ]
{
Quit i%numberA
}
Method numberASet(Arg As %String) As %Status [ ServerOnly = 1 ]
{
s i%numberA = Arg
Quit $$$OK
}
Property numberB As %Decimal [ InitialExpression = 0, Private ];
Method numberBGet() As %String [ ServerOnly = 1 ]
{
Quit i%numberB
}
Method numberBSet(Arg As %String) As %Status [ ServerOnly = 1 ]
{
s i%numberB = Arg
Quit $$$OK
}
Method GetResult() [ Abstract ]
{
s result = 0
q result
}
}
加法類
Class PHA.YX.Design.SimpleFactory.OperationAdd Extends PHA.YX.Design.SimpleFactory.Operation
{
Method GetResult()
{
s reulst = 0
s reulst = ..numberAGet() + ..numberBGet()
q reulst
}
}
減法類
Class PHA.YX.Design.SimpleFactory.OperationSub Extends PHA.YX.Design.SimpleFactory.Operation
{
Method GetResult()
{
s reulst = 0
s reulst = ..numberAGet() - ..numberBGet()
q reulst
}
}
乘法類
Class PHA.YX.Design.SimpleFactory.OperationMul Extends PHA.YX.Design.SimpleFactory.Operation
{
Method GetResult()
{
s reulst = 0
s reulst = ..numberAGet() * ..numberBGet()
q reulst
}
}
除法類
Class PHA.YX.Design.SimpleFactory.OperationDiv Extends PHA.YX.Design.SimpleFactory.Operation
{
Method GetResult()
{
s reulst = 0
q:..numberBGet()=0 "除數(shù)不能為0错英。"
s reulst = ..numberAGet() / ..numberBGet()
q reulst
}
}
指數(shù)類
Class PHA.YX.Design.SimpleFactory.OperationIndex Extends PHA.YX.Design.SimpleFactory.Operation
{
Method GetResult()
{
s reulst = 0
s reulst = ..numberAGet() ** ..numberBGet()
q reulst
}
}
思考
廠家可以生產(chǎn)各種品牌電腦入撒,例如hp,lenovo椭岩,asus等品牌茅逮。簡單工廠模式如何實(shí)現(xiàn)。感興趣的同學(xué)實(shí)現(xiàn)后可以發(fā)我一起參考下判哥。