组合模式,也叫部分整体模式,用于把一组相似的对象当作一个单一的对象,组合模式依据树形结构来组合对象,用来表示部分以及整体层次。属于结构型模式,创建了对象组的树形结构。
将对象组合树形结构以表示“部分-整体”层次结构。使得用户对单个对象和组合对象的使用具有一致性。
主要解决:在树形结构问题中,模糊了简单元素和复杂元素的概念,客户程序可以像处理简单元素一样来处理复杂元素,从而使得客户程序与复杂元素的内部结构解耦。
如何解决:树枝和叶子实现统一接口,树枝内部组合该接口。
关键代码:树枝和叶子实现统一接口,树枝内部组合该接口。
缺点
使用组合模式时,叶子和树枝的声明都是实现类,而不是接口,违反了依赖倒置原则
组合模式有两种实现方式
透明方式
在Component中声明所有用来管理子对象的方法,其中包括Add, Remove等,这样实现Component接口的所有子类都具备了Add和Remove。这样做的好处是叶节点和枝节点对于外界没有区别,具备完全一致的行为接口。但问题也在这里,因为Leaf类本身不具备Add, Remove功能,实现它没有意义。
不透明方式
也是安全的方式,在Component接口中,不去声明Add和Remove方法,那么子类Leaf也不需要去实现。
组合模式和建造者模式都是由子对象构成整体,那么它们有什么区别呢?
1.算术表达式包括操作数、操作符和另一个操作数,其中,另一个操作符也可以是操作数、操作符和另一个操作数。
2.JAVA AWT和SWING中,对于Button和Checkbox是树叶,Container是树枝。
透明方式类图
不透明方式类图
以不透明方式为例
// Company.java
public abstract class Company {
protected String name;
public Company(String name) {
this.name = name;
}
public abstract void add(Company company);
public abstract void remove(Company company);
public abstract void display(int dept); // 显示
public abstract void lineOfDuty(); // 职责
}
// ConcreteCompany.java
public class ConcreteCompany extends Company {
private List<Company> children = new ArrayList<Company>();
public ConcreteCompany(String name) {
super(name);
}
@Override
public void add(Company company) {
children.add(company);
}
@Override
public void remove(Company company) {
children.remove(company);
}
@Override
public void display(int dept) {
int tmp = dept;
while(tmp -- > 0)
System.out.print("-");
System.out.println(name);
for(Company component: children) {
component.display(dept + 2);
}
}
@Override
public void lineOfDuty() {
for(Company component: children) {
component.lineOfDuty();
}
}
}
// HRDepartment.java
public class HRDepartment extends Company {
public HRDepartment(String name) {
super(name);
}
@Override
public void add(Company company) {
}
@Override
public void remove(Company company) {
}
@Override
public void display(int dept) {
while(dept -- > 0)
System.out.print("-");
System.out.println(name);
}
@Override
public void lineOfDuty() {
System.out.println(name + " 员工招聘管理培训");
}
}
// FinanceDepartment.java
public class FinanceDepartment extends Company {
public FinanceDepartment(String name) {
super(name);
}
@Override
public void add(Company company) {
}
@Override
public void remove(Company company) {
}
@Override
public void display(int dept) {
while(dept -- > 0)
System.out.print("-");
System.out.println(name);
}
@Override
public void lineOfDuty() {
System.out.println(name + " 公司财务收支管理");
}
}
// Client.java
public class Client {
public 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(comp);
ConcreteCompany comp1 = new ConcreteCompany("南京办事处");
comp1.add(new HRDepartment("南京办事处人力资源部"));
comp1.add(new FinanceDepartment("南京办事处财务部"));
root.add(comp1);
ConcreteCompany comp2 = new ConcreteCompany("杭州办事处");
comp2.add(new HRDepartment("杭州办事处人力资源部"));
comp2.add(new FinanceDepartment("杭州办事处财务部"));
root.add(comp2);
System.out.println("结构图:");
root.display(1);
System.out.println("职责:");
root.lineOfDuty();
}
}
结构图:
-北京总公司
---总公司人力资源部
---总公司财务部
---上海华东分公司
-----华东分公司人力资源部
-----华东分公司财务部
---南京办事处
-----南京办事处人力资源部
-----南京办事处财务部
---杭州办事处
-----杭州办事处人力资源部
-----杭州办事处财务部
职责:
总公司人力资源部 员工招聘管理培训
总公司财务部 公司财务收支管理
华东分公司人力资源部 员工招聘管理培训
华东分公司财务部 公司财务收支管理
南京办事处人力资源部 员工招聘管理培训
南京办事处财务部 公司财务收支管理
杭州办事处人力资源部 员工招聘管理培训
杭州办事处财务部 公司财务收支管理
原文:https://www.cnblogs.com/fortunely/p/14265077.html