定义
提供一个创建一系列相关或相互依赖的接口,而无需制定它们具体的类。
优点
相比与简单工厂,没有违背开放封闭原则。
可直接创建产品即可。
结构图
描述
连接数据库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()
{
qclass(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()
{
qclass(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()
{
qclass(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()
{
qclass(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"
思考
改写第一章思考生产电脑的例子。感兴趣的同学实现后可以发我一起参考下。