组合模式

组合模式

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

1. UML类图

2. 定义

  • Component抽象构件角色:定义参加组合对象的共有方法和属性,可以定义一些默认的行为或属性
  • Leaf叶子构件:叶子对象,其下再也没有其他的分支,也就是遍历的最小单位
  • Composite树枝构件:树枝对象,它的作用是组合树枝节点和叶子节点形成一个树形结构

3. 通用代码

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

//树枝构件
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;
  }
}

//树叶构件
public class Leaf extends Component{
 //复写父类方法
  public void doSomething(){

  }
}

//场景类
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);
      }
    }
  }
}

4. 应用

4.1 优点

  • 高层模块调用简单:一棵树形机构中的所有节点都是Component,局部和整体对调用者来说没有任何去呗,也就是说,高层模块不必关心自己处理的是单个对象还是整个组合结构,简化了高层模块的代码
  • 节点自由增加:增加树枝节点,树叶节点都很容易,只要找到他的父节点就可以扩展,符合开闭原则

4.2 缺点

在场景类中直接使用了树叶和树枝的实现类,不符合面向接口编程的思想,与依赖倒置的原则冲突。

4.3 使用场景

  • 维护和展示部分-整体关系的场景,如树形菜单、文件和文件夹管理
  • 从一个整体中能够独立出部分模块或功能的场景

5. 透明的组合模式

组合模式有两种不同的实现:透明模式和安全模式,上述所讲的即是安全模式

5.1 UML类图

5.2 透明模式和安全模式

透明模式就是把用来组合使用的方法放到抽象类中,不管叶子对象还是树枝对象都有相同的结构,通过判断getChildren的返回值确认是叶子结点还是树枝节点,如果处理不当,这个会在运行期出现问题,不是很建议的方式;安全模式则将树枝节点和树叶节点彻底分开,树枝节点单独拥有用来组合的方法,这种方法比较安全

5.3 透明模式demo

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

//树枝构件
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;
  }
}

//树叶构件
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();
  }
}

 //通过递归遍历树
  public static void display(Composite root){
    for(Component c : root.getChildren){
      if(c instanceof Leaf){
        c.doSomething();
      }else{
        display(c);
      }
    }
  }

5.4 优点

在遍历的时候不再进行强制类型转化,遵循了依赖倒置原则,方便系统扩展

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值