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.组合模式的案例  ------>  公司各部门层次的关系
创建Company接口
Company.java
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);
            }
        }
    }
}
测试结果
















posted @ 2020-12-29 08:52  喵酱张-Eric  阅读(90)  评论(0编辑  收藏  举报