4组合模式
组合模式
组合模式(Composite Pattern) 也叫合成模式,用来描述部分与整体的关系。
1组合模式的定义
组合模式的英文原文是:
Compose Object into tree structures to represent part-whole hierarchies(层级分类). Composite lets lets clients treat individual objects and compositions of objects uniformly.
意思是:将对象组合成树形结构以表示“部分-整体”的层次结构,使得用户对单个对象和组合对象的使用具有一致性。
组合模式提供的3个角色:
- 抽象构件(Component)角色:该角色定义参加组合对象的共有方法和属性,规范一些默认的行为接口。
- 叶子构件(Leaf)角色:该角色是叶子对象,其下没有其他的分支,定义出参加组合的原始对象的行为。
- 树枝构件(Composite)角色:该角色代表参加组合的、其下有分支的树枝对象,它的作用是将树枝和叶子组合成一个树形结构,并定义出管理子对象的方法,如add()、remove()等。
组合模式类图
创建Component抽象构件
Component.java
package com.eric.结构型模式.组合模式;
/**
* @author Eric
* @ProjectName my_design_23
* @description 抽象构件接口
* @CreateTime 2020-11-30 18:46:56
*/
public interface Component {
public void operation();
}
创建树枝构件
composite.java
package com.eric.结构型模式.组合模式;
import java.util.ArrayList;
/**
* @author Eric
* @ProjectName my_design_23
* @description 树枝构件
* @CreateTime 2020-11-30 18:47:54
*/
public class Composite implements Component{
//构件容器
private ArrayList<Component> componentList = new ArrayList<Component>();
//添加构件
public void add(Component component){
this.componentList.add(component);
}
//删除构件
public void remove(Component component){
this.componentList.remove(component);
}
//获取子构件
public ArrayList<Component> getChild(){
return this.componentList;
}
@Override
public void operation() {
//业务逻辑代码
System.out.println("树枝执行自己的业务中...");
}
}
创建叶子构件
Leaf.java
package com.eric.结构型模式.组合模式;
/**
* @author Eric
* @ProjectName my_design_23
* @description 叶子构件
* @CreateTime 2020-11-30 18:52:19
*/
public class Leaf implements Component {
@Override
public void operation() {
//业务逻辑代码
System.out.println("叶子执行自己的业务中...");
}
}
创建测试类
Client.java
package com.eric.结构型模式.组合模式;
/**
* @author Eric
* @ProjectName my_design_23
* @description 测试类
* @CreateTime 2020-11-30 18:53:01
*/
public class Client {
public static void main(String[] args) {
//创建一个根节点
Composite root = new Composite();
root.operation();
//创建树枝结点
Composite branch = new Composite();
//创建叶子结点
Leaf leaf = new Leaf();
//构件树形结构
root.add(branch);
branch.add(leaf);
dispaly(root);
}
//遍历树(递归)
public static void dispaly(Composite root){
for (Component component : root.getChild()) {
//如果是叶子结点
if(component instanceof Leaf){
component.operation();
}else {
//树枝节点继续遍历
component.operation();
//递归调用
dispaly((Composite) component);
}
}
}
}
测试结果
2组合模式的应用
a.组合模式的优缺点
优点:
- 高层调用简单。一棵树形机构中的所有节点都是Component,局部和整体对调用着来说没有任何区别,即高层模块不必关心自己处理的是单个对象还是整个组合结构,简化了高层模块的代码。
- 节点自由增加。使用组合模式后,如果想增加一个树枝结点、树叶结点只需要找到其父节点即可。
缺点:
- 不易控制树枝构件的类型
- 不宜使用继承的方法来增加新的行为
b.组合模式的使用场景
- 需要描述对象的部分和整体的等级结构,如树形菜单、文件和文件夹管理。
- 需要客户端忽略个体构件与组合构件的区别,平等对待所有的构件。
组合模式也是应用广泛的一种设计模式,例如,Java基础类库的swing部分中就大量使用了组合模式,大部分控件都是JComponent的子类,同时其add()方法有可向界面添加JComponent类型的控件,从而使得使用者可以以统一的方式操作各种控件。
3.组合模式的案例 ------> 公司各部门层次的关系
package com.eric.结构型模式.组合模式.例1;
/**
* @author Eric
* @ProjectName my_design_23
* @description 抽象接口Company
* @CreateTime 2020-11-30 19:40:06
*/
public interface Company {
//获取信息
public String getInfo();
}
创建树枝结点
ConcreteCompany.java
package com.eric.结构型模式.组合模式.例1;
import java.util.ArrayList;
/**
* @author Eric
* @ProjectName my_design_23
* @description 树枝节点类
* @CreateTime 2020-11-30 19:41:17
*/
public class ConcreteCompany implements Company {
private ArrayList<Company> companyList = new ArrayList<Company>();
private String name;//姓名
private String position;//职位
private int salary;//薪水
//构造函数
public ConcreteCompany(String name,String position,int salary){
this.name = name;
this.position = position;
this.salary = salary;
}
//添加
public void add(Company company){
this.companyList.add(company);
}
//删除
public void remove(Company company){
this.companyList.remove(company);
}
//获得所有子构件
public ArrayList<Company> getChild(){
return this.companyList;
}
@Override
public String getInfo() {
String info = "";
info = "名称:" + this.name;
info = info + "\t职位:" + this.position;
info = info + "\t薪水:" + this.salary;
return info;
}
}
创建叶子节点
package com.eric.结构型模式.组合模式.例1;
import java.util.ArrayList;
/**
* @author Eric
* @ProjectName my_design_23
* @description 叶子结点类
* @CreateTime 2020-11-30 19:51:03
*/
public class Employee implements Company {
private String name;//姓名
private String position;//职位
private int salary;//薪水
//构造函数
public Employee(String name,String position,int salary){
this.name = name;
this.position = position;
this.salary = salary;
}
@Override
public String getInfo() {
String info = "";
info = "名称:" + this.name;
info = info + "\t职位:" + this.position;
info = info + "\t薪水:" + this.salary;
return info;
}
}
测试
ClientDemo.java
package com.eric.结构型模式.组合模式.例1;
/**
* @author Eric
* @ProjectName my_design_23
* @description 应用代码
* @CreateTime 2020-11-30 19:53:18
*/
public class ClientDemo {
public static void main(String[] args) {
//CEO
ConcreteCompany root = new ConcreteCompany("Eric", "CEO", 100000000);
//部门经理
ConcreteCompany developDep = new ConcreteCompany("Error", "研发部经理", 700000);
ConcreteCompany saleDep = new ConcreteCompany("Erock", "销售部经理", 400000);
ConcreteCompany financeDep = new ConcreteCompany("zzzz", "财务部经理", 400000);
//部门员工
Employee e1 = new Employee("路人1", "研发部", 90000);
Employee e2 = new Employee("路人2", "研发部", 90000);
Employee e3 = new Employee("路人3", "研发部", 90000);
Employee e4 = new Employee("路人4", "研发部", 90000);
Employee e5 = new Employee("路人5", "研发部", 90000);
Employee e6 = new Employee("路人6", "研发部", 90000);
Employee e7 = new Employee("路人7", "销售部", 90000);
Employee e8 = new Employee("路人8", "销售部", 90000);
Employee e9 = new Employee("路人9", "财务部", 90000);
//生成树
root.add(developDep);
root.add(saleDep);
root.add(financeDep);
developDep.add(e1);
developDep.add(e2);
developDep.add(e3);
developDep.add(e4);
developDep.add(e5);
developDep.add(e6);
saleDep.add(e7);
saleDep.add(e8);
financeDep.add(e9);
//显示公司层次
System.out.println(root.getInfo());
dispaly(root);
}
//遍历树
public static void dispaly(ConcreteCompany root){
for (Company company : root.getChild()) {
if(company instanceof Employee){
System.out.println(company.getInfo());
}else{
System.out.println("\n"+company.getInfo());
dispaly((ConcreteCompany)company);
}
}
}
}
测试结果
只要你不停下来,慢一点也没关系。