组合模式
定义
将对象组合成树形结构以表示”部分-整体“的层析结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。
UML图
透明方式
leaf中add和remove方法实现没有意义,但这样做可以消除叶节点和枝节点对象在抽象层次的区别,它们具备完全一致的接口。
这种方式叫透明方式,在component中声明所有用来管理子对象的方法,在所有子类实现方法,这样叶节点和枝节点对于外界没有区别。
安全方式
安全方式,在component接口不去声明add和remove方法,leaf就无需实现,在composite声明所有用来管理子类对象的方法。缺点是不够透明,所以树叶和树枝类不具有相同的接口,客户端调用需要做判断,带来了不便。
使用场景
当需求中体现的是部分与整体层次结构时,用户希望可以忽略组合对象和单个对象的不同,统一的使用组合结构中的所有对象时,就考虑使用组合模式。组合模式可以让用户一致的使用组合结构和单个对象。
用例
公司管理系统
公司类-抽象类或接口
abstract class Company{
protected String name;
public Company (String name){
this.name = name;
}
public abstract void add(Company c);//增加
public abstract void remove(Company c);//移除
public abstract void display(int depth);//显示
public abstract void lineOfDuty(); //履行职责
}
具体公司类-实现接口,树枝节点
class ConcreteCompany extends Company{
private List<Company> children = new List<Company>();
public ConcreteCompany(String name) {
super(name);
}
@override
public void Add(Company c){
children.add(c);
}
@override
public void Remove(Company c){
children.remove(c);
}
@override
public void Display(int depth){
String message = new String();
for (int i = 0; i < depth; i++)
message += "-";
message += name;
message += "\n";
for (Company company:children)
message += company.display(depth + 2);
return message;
}
//履行职责
@override
public void LineOfDuty(){
String message = new String();
for (Company company:children)
message += company.lineOfDuty();
return message;
}
}
人力资源部与财务部类-叶节点
//人力资源部
class HRDepartment extends Company{
public FinanceDepartment(String name) {
super(name);
}
public override void add(Company c){}
public override void remove(Company c){}
public override void display(int depth){
String message = new String();
for (int i = 0; i < depth; i++)
message += "-";
message += name;
message += "\n";
return message;
}
public override void lineOfDuty(){
System.out.println("员工招聘培训管理:" + name );
}
}
//财务部
class FinanceDepartment extends Company{
public HRDepartment(String name) {
super(name);
}
public override void add(Company c){}
public override void remove(Company c){}
public override void display(int depth){
String message = new String();
for (int i = 0; i < depth; i++)
message += "-";
message += name;
message += "\n";
return message;
}
public override void lineOfDuty(){
System.out.println("公司财务收支管理" + name );
}
}
客户端
static void Main(String[] args){
ConcreteCompany root = new ConcreteCompany("北京总公司");
root.add(new HRDepartment("总公司人力资源部"));
root.add(new FinanceDepartment("总公司财务部"));
ConcreteCompany comp = new ConcreteCompany("上海华东分公司");
comp.add(new HRDepartment("华东分公司人力资源部"));
comp.add(new FinanceDepartment("华东分公司财务部"));
root.add(company);
ConcreteCompany comp1 = new ConcreteCompany("南京办事处");
comp1.add(new HRDepartment("南京办事处人力资源部"));
comp1.add(new FinanceDepartment("南京办事处财务部"));
comp.add(nanjing);
ConcreteCompany comp2 = new ConcreteCompany("杭州办事处");
comp2.add(new HRDepartment("杭州办事处人力资源部"));
comp2.add(new FinanceDepartment("杭州办事处财务部"));
comp.add(hangzhou);
System.out.println("结构图:");
root.display(1);
System.out.println("职责:");
root.lineOfDuty();
}
结果