16-组合模式

组合模式

### 一、定义

将对象组合成树形结构以表示“部分-整体”的层次结构,使得用户对单个对象和组合对象的使用具有一致性

组合模式的通用类图
在这里插入图片描述
Component是抽象构件角色,定义参加组合对象的共有方法和属性,可以定义一些默认的行为或属性。 Leaf是叶子构件,其下再没有其他的分支,是遍历的最小单位。Composite是树枝构件,作用是组合树枝节点和叶子节点形成一个树形结构。

组合模式的通用源码

  1. 抽象构件

    public abstract class Component {
        //个体和整体都具有的共享
        public void doSomething(){
            //编写业务逻辑
        }
    }
    
  2. 树枝构件

    public class Composite extends Component {
        //构件容器
        private ArrayList<Component> componentArrayList = new ArrayList<Component>();
        //增加一个叶子构件或树枝构件
        
        public void add(Component component){
            this.componentArrayList.add(component);
        }
        //删除一个叶子构件或树枝构件
        public void remove(Component component){
            this.componentArrayList.remove(component);
        }
        //获得分支下的所有叶子构件和树枝构件
        public ArrayList<Component> getChildren(){
            return this.componentArrayList;
        }
    }
    
  3. 树叶构件

    public class Leaf extends Component {
        /*
        * 可以覆写父类方法
        * public void doSomething(){
        *
        * }
        */
    }
    
  4. 场景类

    public class Client {
        public static void main(String[] args) {
            //创建一个根节点
            Composite root = new Composite();
            root.doSomething();
            //创建一个树枝构件
            Composite branch = new Composite();
            //创建一个叶子节点
            Leaf leaf = new Leaf();
            //建立整体
            root.add(branch);
            branch.add(leaf);
    	}
    
        //通过递归遍历树
        public static void display(Composite root){
            for(Component c:root.getChildren()){
                if(c instanceof Leaf){ //叶子节点
                	c.doSomething();
                }else{ //树枝节点
                	display((Composite)c);
            	}
        	}
    	}
    }
    

二、组合模式的优点

  • 高层模块调用简单

    树形结构中所有的节点都是Component,局部和整体对调用者来说没有任何区别。

  • 节点自由增加

三、组合模式的缺点

  • 树叶和树枝直接使用了实现类,与依赖倒置原则冲突,限制了接口的影响范围

四、组合模式的使用场景

  • 维护和展示部分-整体关系的场景

    如树形菜单、文件和文件夹管理等

  • 从一个整体能够独立出部分模块或功能的场景

注意:只要是树形结构,就要考虑使用组合模式。只要是体现局部和整体的关系,而且这种关系还比较深时,考虑用组合模式。

五、扩展

  • 组合模式的不同实现:透明模式和安全模式

    上面的为安全模式,透明模式通用类图如下
    在这里插入图片描述
    透明模式是把用来组合使用的方法放到抽象类中,不管叶子对象还是树枝对象都有相同的结构,通过判断getChildren的返回值确认是叶子节点还是树枝节点,如果处理不当,可能会在运行期出现问题。安全模式,把树枝节点和树叶节点彻底分开,树枝节点单独拥有用来组合的方法。

    抽象模式的通用源码

    1. 抽象构件
    public abstract class Component {
      //个体和整体都具有的共享
      public void doSomething(){
          //编写业务逻辑
      }
      //增加一个叶子构件或树枝构件
      public abstract void add(Component component);
      //删除一个叶子构件或树枝构件
      public abstract void remove(Component component);
      //获得分支下的所有叶子构件和树枝构件
      public abstract ArrayList<Component> getChildren();
    }
    
    1. 树叶节点

       public class Leaf extends Component {
        @Deprecated
        public void add(Component component) throws UnsupportedOperationException{
            //空实现,直接抛弃一个"不支持请求"异常
            throw new UnsupportedOperationException();
        }
        @Deprecated
        public void remove(Component component)throws UnsupportedOperationException{
            //空实现
            throw new UnsupportedOperationException();
        }
        @Deprecated
        public ArrayList<Component> getChildren()throws UnsupportedOperationException{
            //空实现
             throw new UnsupportedOperationException();
        }
       }
      
    2. 树结构遍历

       public class Client {
        //通过递归遍历树
        public static void display(Component root){
            for(Component c:root.getChildren()){
                if(c instanceof Leaf){ //叶子节点
                	c.doSomething();
                }else{ //树枝节点
               	 	display(c);
                }
            }
        }
       }
      
  • 组合模式的遍历

    上述树的遍历可以实现从上到下的遍历(根节点到叶子节点),从下往上遍历(子节点到父节点)实现方式只要添加两个方法,setParent设置父节点是谁,getParent查找父节点。即可

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值