第十一章 Caché 設計模式 抽象工廠模式
定義
提供一個創建一系列相關或相互依賴的接口,而無需制定它們具體的類。
優點
- 相比與簡單工廠,沒有違背開放封閉原則。
- 可直接創建產品即可。
結構圖
描述
連接數據庫SQL和Caché並且每個數據庫映射的同張的表的類型是不同的。
完整示例
實體類
Class PHA.YX.Design.AbstractFactory.User Extends %RegisteredObject
{
Property ID As %String;
Method IDGet() As %String [ ServerOnly = 1 ]
{
Quit i%ID
}
Method IDSet(Arg As %String) As %Status [ ServerOnly = 1 ]
{
s i%ID = Arg
Quit $$$OK
}
Property name As %String;
Method nameGet() As %String [ ServerOnly = 1 ]
{
Quit i%name
}
Method nameSet(Arg As %String) As %Status [ ServerOnly = 1 ]
{
s i%name = Arg
Quit $$$OK
}
}
Class PHA.YX.Design.AbstractFactory.Department Extends %RegisteredObject
{
Property ID As %String;
Method IDGet() As %String [ ServerOnly = 1 ]
{
Quit i%ID
}
Method IDSet(Arg As %String) As %Status [ ServerOnly = 1 ]
{
s i%ID = Arg
Quit $$$OK
}
Property name As %String;
Method nameGet() As %String [ ServerOnly = 1 ]
{
Quit i%name
}
Method nameSet(Arg As %String) As %Status [ ServerOnly = 1 ]
{
s i%name = Arg
Quit $$$OK
}
}
抽象產品類
Class PHA.YX.Design.AbstractFactory.IDepartment Extends %RegisteredObject
{
Method Insert(department As Department)
{
}
Method GetDepartment(ID As %Integer)
{
}
}
Class PHA.YX.Design.AbstractFactory.IUser Extends %RegisteredObject
{
Method Insert(user As User)
{
}
Method GetUser(ID As %Integer)
{
}
}
具體產品類
User
Class PHA.YX.Design.AbstractFactory.SqlUser Extends IUser
{
Method Insert(user As User)
{
w "在SQL中給User表添加一條記錄",!
}
Method GetUser(ID As %Integer)
{
w "在SQL中根據ID得到User表一條記錄",!
}
ClassMethod CreatObject()
{
q ##class(PHA.YX.Design.AbstractFactory.SqlUser).%New()
}
}
Class PHA.YX.Design.AbstractFactory.CacheUser Extends IUser
{
Method Insert(user As User)
{
w "在Cache中給User表添加一條記錄",!
}
Method GetUser(ID As %Integer)
{
w "在Cache中根據ID得到User表一條記錄",!
}
ClassMethod CreatObject()
{
q ##class(PHA.YX.Design.AbstractFactory.CacheUser).%New()
}
}
Department
Class PHA.YX.Design.AbstractFactory.SqlDepartment Extends IDepartment
{
Method Insert(department As Department)
{
w "在SQL中給Department表添加一條記錄",!
}
Method GetDepartment(ID As %Integer)
{
w "在SQL中根據ID得到Department表一條記錄",!
}
ClassMethod CreatObject()
{
q ##class(PHA.YX.Design.AbstractFactory.SqlDepartment).%New()
}
}
Class PHA.YX.Design.AbstractFactory.CacheDepartment Extends IDepartment
{
Method Insert(department As Department)
{
w "在Cache中給Department表添加一條記錄",!
}
Method GetDepartment(ID As %Integer)
{
w "在Cache中根據ID得到Department表一條記錄",!
}
ClassMethod CreatObject()
{
q ##class(PHA.YX.Design.AbstractFactory.CacheDepartment).%New()
}
}
抽象工廠類
- 因爲Caché 系統$反射方法沒有創建對象的方法。所以採用了一種討巧的方式.
- $classmethod 可以直接調用靜態方法。
- 通過給實體類創建一個靜態方法返回該對象的實例。
- 直接用XECUTE命令直接反射,然後獲取引用對象。
- 配置的字符串可以通過inc文件來制定,符合開放封閉原則,又可配置。
注意:本章使用的反射+配置實現訪問程序
Include PHA.YX.Design.AbstractFactory.Data
Class PHA.YX.Design.AbstractFactory.DataAccess Extends %RegisteredObject
{
Parameter sqlDatabase = "Sql";
Parameter cacheDatabase = "Cache";
ClassMethod CreateUser() As IUser
{
# dim mUser as PHA.YX.Design.AbstractFactory.IUser
s classNmae = "PHA.YX.Design.AbstractFactory." _ ..#sqlDatabase _ "User"
s mUser = $classmethod(classNmae,"CreatObject")
q mUser
}
ClassMethod CreateDepartment() As IDepartment
{
# dim mUser as PHA.YX.Design.AbstractFactory.IDepartment
s classNmae = "PHA.YX.Design.AbstractFactory." _ ..#sqlDatabase _ "Department"
s mUser = $classmethod(classNmae,"CreatObject")
q mUser
}
ClassMethod CreateUserTwo() As IUser
{
# dim mUser as PHA.YX.Design.AbstractFactory.IUser
s classNmae = "PHA.YX.Design.AbstractFactory." _ $$$database _ "User"
x ("(mUser) s mUser = ##class(" _ classNmae _ ").%New()", .mUser)
q mUser
}
}
#define database "Cache"
思考
改寫第一章思考生產電腦的例子。感興趣的同學實現後可以發我一起參考下。