结构设计模式之组合模式

  1. 模式结构
    1. 概念:组合多个对象形成树形结构以表示具有部分-整体关系的层次结构。组合模式让客户端可以统一对待单个对象和组合对象。
    2. 结构:抽象构件Component + 叶子构件Leaf + 容器构件Composite
    3. 分类区别
      透明组合模式抽象构件Component中声明了所有用于管理成员对象的方法,包括add()、remove()、getChild()等方法。这样做的好处是确保所有的构件类都有相同的接口。在客户端看来,叶子对象与容器对象所提供的方法是一致的,客户端可以一致地对待所有的对象。
      安全组合模式抽象构件Component没有声明任何用户管理成员对象的方法,而是在Composite声明并实现这些方法。这种做法是安全的,因为根本不向叶子对象提供这些管理成员对象的方,对于叶子对象,客户端不可能调用到这些方法。
  2. 适用场景
    1. 在具有整体和部分的层次结构中希望通过一种方式忽略整体与部分的差异,客户端可以一致地对待他们。
    2. 在一个使用面向对象语言开发的系统中需要处理一个树形结构。树形结构随处可见,如操作系统中的菜单结构、目录结构、公司的组织结构、xml文件、html文件、jsp文件等。
    3. 在一个系统中能够分离出叶子对象和容器对象,而且他们的类型不固定,需要增加一些新的类型。
  3. 实例
    1. 现在有个开发一个xml文档处理软件的需求,可以根据关键字查询指定内容,用户可以在xml中任意选取某一结点作为查询的初始结点,无需关心该结点所处的层次结构。针对该需求使用组合模式进行设计。
    2. 假设xml结构如下:
      <a name="a">
          <b name="b">
              <c name="c" content="c"/>
              <d name="d" content="d"/>
          </b>
          <e name="e">
              <f name="f" content="f"/>
              <g name="g">
                  <h name="h" content="h"/>
                  <i name="i" content="i"/>
              </g>
          </e>
      </a>
      public interface Component {
          public void findContent(String conent);
      }
      
      public class Leaf implements Component {
      
          private String name;
          private String content;
      
          public Leaf(String name,String content) {
              this.name = name;
              this.content = content;
          }
      
          @Override
          public void findContent(String conent) {
              if(this.content.equals(conent)){
                  System.out.print( "已找到:" + this.name + "叶子包含" + conent + ",倒序索引:");
              }else{
                  System.out.println( name + "叶子不包含" + conent);
              }
          }
      }
      
      public class Composite implements Component {
      
          private ArrayList<Component> list = new ArrayList<Component>();
      
          private String name;
      
          public Composite(String name) {
              this.name = name;
          }
      
          //添加叶节点
          public void add(Component component){
              list.add(component);
          }
      
          //删除叶节点
          public void remove(Component component){
              list.remove(component);
          }
      
          //根据索引查询叶节点
          public Component getChild(Integer index){
              return list.get(index);
          }
      
          @Override
          public void findContent(String conent) {
              System.out.print("递归查找容器" + this.name + ",");
              for (Component component: list){
                  component.findContent(conent);
              }
              System.out.print(this.name + "<--");
          }
      }
      
      public class Client {
          public static void main(String[] args) {
              Component c,d,f,h,i;
              Composite a,b,e,g;
      
              //叶子结点
              c = new Leaf("c","c");
              d = new Leaf("d","d");
              f = new Leaf("f","f");
              h = new Leaf("h","h");
              i = new Leaf("i","i");
      
              //容器结点
              a = new Composite("a");
              b = new Composite("b");
              e = new Composite("e");
              g = new Composite("g");
      
              //封装叶子与容器
              b.add(c);
              b.add(d);
              a.add(b);
      
              g.add(h);
              g.add(i);
              e.add(f);
              e.add(g);
              a.add(e);
      
              //查找叶子
              a.findContent("i");
          }
      }
      
      控制台输出:
      递归查找容器a,递归查找容器b,c叶子不包含i
      d叶子不包含i
      b<--递归查找容器e,f叶子不包含i
      递归查找容器g,h叶子不包含i
      已找到:i叶子包含i,倒序索引:g<--e<--a<--
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值