美文网首页
第4章 结构型模式-组合模式

第4章 结构型模式-组合模式

作者: 一介书生独醉江湖 | 来源:发表于2022-06-20 10:18 被阅读0次
    结构型模式的目的是通过组合类或对象产生更大结构,以适应更高层次的逻辑需求;
    
    结构型模式共有7种:
    ■ 代理模式
    ■ 装饰模式
    ■ 适配器模式
    ■ 组合模式
    ■ 桥梁模式
    ■ 外观模式
    ■ 享元模式
    
    一、组合模式简介
    组合模式(Composite Pattern)也叫合成模式,用来描述部分与整体的关系;
    将对象组合成树形结构以表示“部分—整体”的层次结构,使得用户对单个对象和组合对象的使用具有一致性;
    
    # 组合模式3个角色
    ■ 抽象构件(Component)角色:该角色定义参加组合对象的共有方法和属性,规范一些默认的行为接口;
    ■ 叶子构件(Leaf)角色:该角色是叶子对象,其下没有其他的分支,定义出参加组合的原始对象的行为;
    ■ 树枝构件(Composite)角色:该角色代表参加组合的、其下有分支的树枝对象;
      它的作用是将树枝和叶子组合成一个树形结构,并定义出管理子对象的方法,如add()、remove()等;
    
    image.png
    /**
     * 抽象构件
     */
    public interface Component {
    
        void operation();
    
    }
    
    /**
     * 树枝构件
     */
    public class Composite implements Component{
    
        private List<Component> componentList = new ArrayList<>();
    
        // 添加构件
        public void add(Component component){
            this.componentList.add(component);
        }
    
        // 删除构件
        public void remove(Component component){
            this.componentList.remove(component);
        }
    
        // 获取子构件
        public List<Component> getChildList(){
            return this.componentList;
        }
    
        // 业务逻辑代码
        @Override
        public void operation() {
            System.out.println("树枝构件业务逻辑代码");
        }
    }
    
    /**
     * 叶子构件
     */
    public class Leaf implements Component{
    
        // 业务逻辑代码
        @Override
        public void operation() {
            System.out.println("叶子构件业务逻辑代码");
        }
    }
    
    
    /**
     * 应用代码
     */
    public class ClientDemo {
    
        public static void main(String[] args){
    
            // 创建一个根节点
            Composite root = new Composite();
    
            // 创建树枝节点
            Composite branch = new Composite();
    
            // 创建叶子节点
            Leaf leaf = new Leaf();
    
            // 创建树形结构
            root.add(branch);
            branch.add(leaf);
    
            display(root);
        }
        // 遍历树(递归)
        public static void display(Composite root){
            for(Component c : root.getChildList()){
                // 叶子节点
                if(c instanceof Leaf){
                    c.operation();
                }else{
                // 树枝节点
                    c.operation();
                    display((Composite)c);
                }
            }
        }
    }
    
    # 控制台输出:
    树枝构件业务逻辑代码
    叶子构件业务逻辑代码
    
    二、组合模式的优缺点
    # 组合模式的优点
    ■ 高层模块调用简单;
      一棵树形机构中的所有节点都是Component;
    ■ 节点自由增加;
      使用组合模式后,如果想增加一个树枝节点、树叶节点只需要找到其父节点即可;
    
    # 组合模式的缺点
    ■ 不易控制树枝构件的类型;
    ■ 不易使用继承的方法来增加新的行为;
    
    三、组合模式的使用场景
    ■ 需要描述对象的部分和整体的等级结构,如树形菜单、文件和文件夹管理;
    ■ 需要客户端忽略个体构件和组合构件的区别,平等对待所有的构件;
    
    、组合模式的实例
    # 使用组合模式实现公司各部门层次关系;
    
    image.png
    /**
     * 抽象接口
     */
    public interface Company {
    
        // 获取信息
        String getInfo();
    }
    
    
    import java.util.ArrayList;
    import java.util.List;
    
    /**
     * 树枝节点
     */
    public class ConcreteCompany implements Company{
    
        private List<Company> companyList = new ArrayList<>();
    
        // 姓名
        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 List<Company> getChild(){
            return companyList;
        }
        @Override
        public String getInfo() {
            return "公司{" +
                    "  姓名 ='" + name + '\'' +
                    ", 职位 ='" + position + '\'' +
                    ", 薪水 ='" + salary + '\'' +
                    '}';
        }
    
    }
    
    
    
    /**
     * 叶子节点
     */
    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() {
            return "公司{" +
                    "  姓名 ='" + name + '\'' +
                    ", 职位 ='" + position + '\'' +
                    ", 薪水 ='" + salary + '\'' +
                    '}';
        }
    }
    
    
    
    /**
     * 应用代码
     */
    public class ClientDemo {
    
    
        public static void main(String[] args){
            ConcreteCompany root = new ConcreteCompany("张三","CEO",100000);
            ConcreteCompany developDep = new ConcreteCompany("李四","研发部经理",12000);
            ConcreteCompany salesDep = new ConcreteCompany("王五","销售部经理",15000);
            ConcreteCompany financeDep = new ConcreteCompany("马六","财务部经理",10000);
    
            Employee e1 = new Employee("A","研发部",1000);
            Employee e2 = new Employee("B","研发部",1100);
            Employee e3 = new Employee("C","研发部",1200);
            Employee e4 = new Employee("D","研发部",1300);
            Employee e5 = new Employee("E","研发部",1400);
    
            Employee e6 = new Employee("F","销售部",1500);
            Employee e7 = new Employee("G","销售部",1600);
            Employee e8 = new Employee("H","销售部",1700);
            Employee e9 = new Employee("I","销售部",1800);
    
            Employee e10 = new Employee("J","财务部",1900);
            Employee e11 = new Employee("K","财务部",2000);
            Employee e12 = new Employee("L","财务部",2100);
            Employee e13 = new Employee("M","财务部",2200);
            Employee e14 = new Employee("N","财务部",2300);
    
            // 生成树
            root.add(developDep);
            root.add(salesDep);
            root.add(financeDep);
    
            developDep.add(e1);
            developDep.add(e2);
            developDep.add(e3);
            developDep.add(e4);
            developDep.add(e5);
    
            salesDep.add(e6);
            salesDep.add(e7);
            salesDep.add(e8);
            salesDep.add(e9);
    
            financeDep.add(e10);
            financeDep.add(e11);
            financeDep.add(e12);
            financeDep.add(e13);
            financeDep.add(e14);
    
            // 显示公司层次
            System.out.println(root.getInfo());
            display(root);
        }
    
        public static void display(ConcreteCompany root){
            for(Company c : root.getChild()){
                if(c instanceof Employee){
                    System.out.println(c.getInfo());
                }else{
                    System.out.println("\n" + c.getInfo());
                    // 递归
                    display((ConcreteCompany)c);
                }
            }
        }
    }
    
    # 控制台输出:
    公司{  姓名 ='张三', 职位 ='CEO', 薪水 ='100000'}
    
    公司{  姓名 ='李四', 职位 ='研发部经理', 薪水 ='12000'}
    公司{  姓名 ='A', 职位 ='研发部', 薪水 ='1000'}
    公司{  姓名 ='B', 职位 ='研发部', 薪水 ='1100'}
    公司{  姓名 ='C', 职位 ='研发部', 薪水 ='1200'}
    公司{  姓名 ='D', 职位 ='研发部', 薪水 ='1300'}
    公司{  姓名 ='E', 职位 ='研发部', 薪水 ='1400'}
    
    公司{  姓名 ='王五', 职位 ='销售部经理', 薪水 ='15000'}
    公司{  姓名 ='F', 职位 ='销售部', 薪水 ='1500'}
    公司{  姓名 ='G', 职位 ='销售部', 薪水 ='1600'}
    公司{  姓名 ='H', 职位 ='销售部', 薪水 ='1700'}
    公司{  姓名 ='I', 职位 ='销售部', 薪水 ='1800'}
    
    公司{  姓名 ='马六', 职位 ='财务部经理', 薪水 ='10000'}
    公司{  姓名 ='J', 职位 ='财务部', 薪水 ='1900'}
    公司{  姓名 ='K', 职位 ='财务部', 薪水 ='2000'}
    公司{  姓名 ='L', 职位 ='财务部', 薪水 ='2100'}
    公司{  姓名 ='M', 职位 ='财务部', 薪水 ='2200'}
    公司{  姓名 ='N', 职位 ='财务部', 薪水 ='2300'}
    
    参考:
    摘录 《设计模式(Java版)》韩敬海主编;(微信读书APP中有资源,可以直接阅读)
    # 以前是免费的,不知道从什么时候起,需要15.6书币才能阅读全文了(只免费前两章了),所以只能花书币买了;
    

    相关文章

      网友评论

          本文标题:第4章 结构型模式-组合模式

          本文链接:https://www.haomeiwen.com/subject/xuvqvrtx.html