第十五章 Caché 设计模式 组合模式
定义
将对象组合成树形结构以表示“部分-整体”的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。
使用场景
需求中是体现部分与整体层次的结构时,可以忽略组合对象与单个对象的不同,统一地使用组合结构中的所有对象时,就应该考虑用组合模式了。
优点
- 组合模式可以以层次结构清楚的定义复杂对象。让高层次忽略层次差异。
- 高层次可以使用统一的方法而不用担心它是枝干还是叶子。
- 组合模式可以形成复杂的树形结构,但对树形机构的控制却非常简单。
缺点
- 叶子类型不能控制。
结构图
思考
总公司,分公司都有HR部门,财政部门,总公司有多个分公司。
完整示例
抽象类
Class PHA.YX.Design.Composite.Company Extends %RegisteredObject
{
Property name As %String;
Method %OnNew(name As %String) As %Status [ Private, ServerOnly = 1 ]
{
s ..name = name
Quit $$$OK
}
Method Add(c As Company)
{
}
Method Remove(c As Company)
{
}
Method Display(depth As %Integer)
{
}
Method LineOfDuty()
{
}
}
具体类
树枝节点
Class PHA.YX.Design.Composite.ConcreteCompany Extends Company
{
Property children As list Of Company;
Method %OnNew(name As %String) As %Status [ Private, ServerOnly = 1 ]
{
d ##super(name)
Quit $$$OK
}
Method Add(c As Company)
{
d ..children.Insert(c)
}
Method Remove(c As Company)
{
d ..children.RemoveAt(c)
}
Method Display(depth As %Integer)
{
w depth _ "级" _ ..name,!
f i = 1 : 1 : ..children.Size d
.d ..children.GetAt(i).Display(depth + 1)
}
Method LineOfDuty()
{
f i = 1 : 1 : ..children.Size d
.d ..children.GetAt(i).LineOfDuty()
}
}
树叶节点
Class PHA.YX.Design.Composite.HRDepartment Extends Company
{
Method %OnNew(name As %String) As %Status [ Private, ServerOnly = 1 ]
{
d ##super(name)
Quit $$$OK
}
Method Add(c As Company)
{
}
Method Remove(c As Company)
{
}
Method Display(depth As %Integer)
{
w depth _ "级" _ ..name,!
}
Method LineOfDuty()
{
w ..name _ "员工招聘培训管理",!
}
}
Class PHA.YX.Design.Composite.FinanceDepartment Extends Company
{
Method %OnNew(name As %String) As %Status [ Private, ServerOnly = 1 ]
{
d ##super(name)
Quit $$$OK
}
Method Add(c As Company)
{
}
Method Remove(c As Company)
{
}
Method Display(depth As %Integer)
{
w depth _ "级" _ ..name,!
}
Method LineOfDuty()
{
w ..name _ "公司财务收支管理",!
}
}
调用
/// d ##class(PHA.YX.Design.Program).Composite()
ClassMethod Composite()
{
#dim root as PHA.YX.Design.Composite.ConcreteCompany
s root = ##class(PHA.YX.Design.Composite.ConcreteCompany).%New("北京总公司")
d root.Add(##class(PHA.YX.Design.Composite.HRDepartment).%New("总公司人力资源部"))
d root.Add(##class(PHA.YX.Design.Composite.HRDepartment).%New("总公司财务部"))
#dim comp as PHA.YX.Design.Composite.ConcreteCompany
s comp = ##class(PHA.YX.Design.Composite.ConcreteCompany).%New("天津分公司")
d comp.Add(##class(PHA.YX.Design.Composite.HRDepartment).%New("天津公司人力资源部"))
d comp.Add(##class(PHA.YX.Design.Composite.HRDepartment).%New("天津公司财务部"))
d root.Add(comp)
#dim comp1 as PHA.YX.Design.Composite.ConcreteCompany
s comp1 = ##class(PHA.YX.Design.Composite.ConcreteCompany).%New("火星分公司")
d comp1.Add(##class(PHA.YX.Design.Composite.HRDepartment).%New("火星公司人力资源部"))
d comp1.Add(##class(PHA.YX.Design.Composite.HRDepartment).%New("火星公司财务部"))
d comp.Add(comp1)
#dim comp2 as PHA.YX.Design.Composite.ConcreteCompany
s comp2 = ##class(PHA.YX.Design.Composite.ConcreteCompany).%New("三体分公司")
d comp2.Add(##class(PHA.YX.Design.Composite.HRDepartment).%New("三体公司人力资源部"))
d comp2.Add(##class(PHA.YX.Design.Composite.HRDepartment).%New("三体公司财务部"))
d comp.Add(comp2)
w "结构图",!
d root.Display(1)
w "职责",!
d root.LineOfDuty()
}
DHC-APP>d ##class(PHA.YX.Design.Program).Composite()
结构图
1级北京总公司
2级总公司人力资源部
2级总公司财务部
2级天津分公司
3级天津公司人力资源部
3级天津公司财务部
3级火星分公司
4级火星公司人力资源部
4级火星公司财务部
3级三体分公司
4级三体公司人力资源部
4级三体公司财务部
职责
总公司人力资源部员工招聘培训管理
总公司财务部员工招聘培训管理
天津公司人力资源部员工招聘培训管理
天津公司财务部员工招聘培训管理
火星公司人力资源部员工招聘培训管理
火星公司财务部员工招聘培训管理
三体公司人力资源部员工招聘培训管理
三体公司财务部员工招聘培训管理
思考
画出本组产品线结构组织图。