定义:
组合模式也叫合成模式,用来描述整体与部分的关系
将对象组合成树形结构以表示“部分—整体”的层次结构,使得用户对单位对象和组合对象的使用具有一致性。
角色:
- 抽象构件:该角色定义参加组合对象的共有方法和属性,规范一些默认的行为接口。
- 叶子构件:叶子对象,旗下没有分支
- 树枝构件:代表参加组合的,旗下有分支的树枝对象,他的作用是将树枝和叶子组合成一个树形结构,并定义出管理子类对象的方法,入add remove
优点:
- 高层模块调用简单,局部和整体对调用者来说没有任何区别,高层模块不担心自己处理的是单个对象还是整个组合结构,简化了高层模块的代码
- 结点自由增加,使用组合模式后,如果像增加一个树枝结点、树叶结点只需要找到其父结点即可
缺点:
- 不容易控制树枝结构的类型
- 不易使用继承的方法来增加新的行为
使用场景:
- 需要描述对象的部分和整体的等级结构,如树形菜单、文件、文件夹
- 需要客户端忽略个体构件和组合构的区别,平等对待所有构件
Java基础类库的swing部分种就大量使用了组合模式,大部分组件都是JComponent的子类,同时其add方法又可向外界添加JComponent类型的控件,从而使得使用者可以以统一的方式操作各种控件
实例:公司层次关系
package 组合模式;
public interface Company {
public void getInfo();
}
package 组合模式;
import java.util.ArrayList;
public class ConcreteCompany implements Company{
private ArrayList<Company> list = new ArrayList<Company>();
private String name;
private String postition; //职位
private String salary; //薪水
public ConcreteCompany(String name,String postition,String salary) {
// TODO 自动生成的构造函数存根
this.name = name;
this.postition = postition;
this.salary = salary;
}
public void add(Company company){
list.add(company);
}
public void remove(Company company){
list.remove(company);
}
public ArrayList<Company> getlist(){
return list;
}
@Override
public void getInfo() {
// TODO 自动生成的方法存根
System.out.println("名称:"+this.name+"\t职位:"+this.postition+"\t薪水:"+this.salary);
}
}
package 组合模式;
public class Employee implements Company{
private String name;
private String postition; //职位
private String salary; //薪水
public Employee(String name,String postition,String salary) {
// TODO 自动生成的构造函数存根
this.name = name;
this.postition = postition;
this.salary = salary;
}
@Override
public void getInfo() {
// TODO 自动生成的方法存根
System.out.println("名称:"+this.name+"\t职位:"+this.postition+"\t薪水:"+this.salary);
}
}
package 组合模式;
public class Main {
public static void display(ConcreteCompany people){
for(Company company:people.getlist()){
if (company instanceof Employee) {
company.getInfo();
}else{
System.out.println();
display((ConcreteCompany)company);
}
}
}
public static void main(String[] args) {
// TODO 自动生成的方法存根
//CEO
ConcreteCompany ceo = new ConcreteCompany("强月城", "CEO", "1000000");
//经理
ConcreteCompany developDep = new ConcreteCompany("张三", "研发部经理", "12000");
ConcreteCompany salesDep = new ConcreteCompany("李四", "销售部经理", "10000");
ConcreteCompany finenceDep = new ConcreteCompany("王五", "财务部经理", "11000");
//员工
Employee e1 = new Employee("老A", "研发部", "5000");
Employee e2 = new Employee("老B", "研发部", "5000");
Employee e3 = new Employee("老C", "研发部", "5000");
Employee e4 = new Employee("老D", "销售部", "4000");
Employee e5 = new Employee("老E", "销售部", "4000");
Employee e6 = new Employee("老F", "销售部", "4000");
Employee e7 = new Employee("老G", "销售部", "4500");
Employee e8 = new Employee("老H", "销售部", "4500");
Employee e9 = new Employee("老I", "销售部", "4500");
ceo.add(developDep);
ceo.add(salesDep);
ceo.add(finenceDep);
developDep.add(e1);
developDep.add(e2);
developDep.add(e3);
salesDep.add(e4);
salesDep.add(e5);
salesDep.add(e6);
finenceDep.add(e7);
finenceDep.add(e8);
finenceDep.add(e9);
ceo.getInfo();
display(ceo);
}
}
名称:强月城 职位:CEO 薪水:1000000
名称:老A 职位:研发部 薪水:5000
名称:老B 职位:研发部 薪水:5000
名称:老C 职位:研发部 薪水:5000名称:老D 职位:销售部 薪水:4000
名称:老E 职位:销售部 薪水:4000
名称:老F 职位:销售部 薪水:4000名称:老G 职位:销售部 薪水:4500
名称:老H 职位:销售部 薪水:4500
名称:老I 职位:销售部 薪水:4500