zoukankan      html  css  js  c++  java
  • 设计模式-组合模式(10)

    定义

      组合(Composite Pattern)模式也叫合成模式,用来描述部分与整体的关系。英文原话是:Compose objects into tree structures to represent part-whole hierarchies.Composite lets clients treat individual object and compositions of objects uniformly.意思是:将对象组合成树形结构以表示"部分-整体"的层次结构,使得用户对单个对象和组合对象的使用具有一致性

      组合模式分为三个角色:

      1.抽象构件(Component)角色:该角色定义参加组合的对象的共有方法和属性,规范一些默认的行为接口。

      2.叶子构件(Leaf)角色:该角色是叶子对象,其下没有其他的分支,定义出参加组合的原始对象的行为。

      3.树枝构件(Composite)角色:该角色代表参加组合的、其下有分支的树枝对象,它的作用是将树枝和叶子组合成一个树形结构,并定义出管理子对象的方法,如add()、remove()等。

    //定义抽象构建接口
    public interface Component {
        public void operation();
    }
    
    /**
     * 树枝构件 
     */
    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(this.toString()+"树枝构建业务");
        }
    }
    
    /**
     * 叶子构件 
     */
    public class Leaf implements Component {
        @Override
        public void operation() {
            //省略业务逻辑代码
            System.out.println(this.toString()+"叶子构建业务");
        }
    }
    
    /**
     * 调用 
     */
    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);
            
            display(root);
        }
        
        //遍历树(递归)
        public static void display(Composite root){
            for (Component c:root.getChild()) {
                if (c instanceof Leaf) {    //如果节点类型是叶子节点
                    c.operation();
                }else {    //树枝节点
                    c.operation();
                    display((Composite)c);
                }
            }
        }
    }

    源码

    组合模式优点

    • 高层模块调用简单。一颗树形机构的所有节点都是Component,局部和整体对于调用者来说没有任何区别,即高层模块不必关心自己处理的是单个对象还是整个组合结构,简化了高层模块的代码。
    • 节点自由增加。使用组合模式后,如果想增加树枝节点、树叶节点,只需找到其父节点即可。

    组合模式缺点

    • 不易控制树枝构件的类型。
    • 不易使用继承的方法来增加新的行为。

    使用场景

    • 需要描述对象的部分和整体之间的等级结构关系,如树形菜单、文件和文件夹管理等。
    • 需要客户端忽略个体构件和组合构件的区别,平等的对待所有的构建。

      组合模式也是应用广泛的一种设计模式。例如,java基础类库的swing部分就是大量使用了组合模式,其中大部分控件都是JComponent的子类,同时其add()方法又可向界面添加JComponent类型的控件,从而使得使用者能够以统一的方式操作各种控件。

    /**
     * 抽象接口
     */
    public interface Company {
        //获取信息
        public String getInfo();
    }
    
    /**
     * 树枝节点类 
     */
    public class ConcreteCompany implements Company{
        //构件容器
        private ArrayList<Company> companyList = new ArrayList<Company>();
        
        private String name;
        private String sex;
        private String position;
        private int salary;
        
        public ConcreteCompany(String name,String sex, String position, int salary) {
            this.name = name;
            this.sex = sex;
            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+="	性别"+this.sex;
            info+="	职位"+this.position;
            info+="	薪水"+this.salary;
            return info;
        }
    
    }
    
    /**
     * 叶子节点类
     */
    public class Employee implements Company{
        private String name;
        private String sex;
        private String position;
        private int salary;
        
        public Employee(String name,String sex, String position, int salary) {
            this.name = name;
            this.sex = sex;
            this.position = position;
            this.salary = salary;
        }
        
        @Override
        public String getInfo() {
            String info = "";
            info = "名称:"+this.name;
            info+="	性别"+this.sex;
            info+="	职位"+this.position;
            info+="	薪水"+this.salary;
            return info;
        }
    
    }
    
    //调用
    public class DemoClient {
        public static void main(String[] args) {
            //CEO
            ConcreteCompany root = new ConcreteCompany("李彦宏", "男", "CEO", 1000000);
            //部门经理
            ConcreteCompany developDep = new ConcreteCompany("郑亮", "男", "研发部经理", 9999999);
            ConcreteCompany salesDep = new ConcreteCompany("逍遥", "男", "销售部经理", 8888888);
            ConcreteCompany financeDep = new ConcreteCompany("小颖", "女", "财务不经理", 6666666);
            //部门员工
            Employee e1 = new Employee("程序甲", "男", "java开发工程师", 10000);
            Employee e2 = new Employee("素材乙", "女", "素材师", 8888);
            Employee e3 = new Employee("UI丙", "男", "UI设计师", 8888);
            Employee e4 = new Employee("销售员甲", "男", "销售员", 6666);
            Employee e5 = new Employee("销售员乙", "男", "销售员", 6666);
            Employee e6 = new Employee("会计甲", "男", "会计", 5000);
            //生成树
            root.add(developDep);
            root.add(salesDep);
            root.add(financeDep);
            developDep.add(e1);
            developDep.add(e2);
            developDep.add(e3);
            salesDep.add(e4);
            salesDep.add(e5);
            financeDep.add(e6);
            //递归树
            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("
    "+c.getInfo());
                    display((ConcreteCompany) c);
                }
            }
        } 
        
    }

    源码

  • 相关阅读:
    Execution Order of Event Functions
    【转】unity自带寻路Navmesh入门教程(三)
    【转】unity自带寻路Navmesh入门教程(二)
    【转】unity自带寻路Navmesh入门教程(一)
    【转】UGUI EventSystem
    【转】超简单利用UGUI制作圆形小地图
    【转】UGUI(小地图的实现)与游戏关卡选择的简单实现
    【转】UGUI实现unity摇杆
    redis aof持久化遇到的Can't open the append-only file Permissi
    redis aof持久化遇到的Can't open the append-only file Permissi
  • 原文地址:https://www.cnblogs.com/aeolian/p/7989600.html
Copyright © 2011-2022 走看看