zoukankan      html  css  js  c++  java
  • 11、Composite 组合模式 容器与内容的一致性(抽象化) 结构型设计模式

    1、Composite模式定义

    组合模式(Composite Pattern),又叫部分整体模式,是用于把一组相似的对象当作一个单一的对象。组合模式依据树形结构来组合对象,用来表示部分以及整体层次。这种类型的设计模式属于结构型模式,它创建了对象组的树形结构。

    这种模式创建了一个包含自己对象组的类。该类提供了修改相同对象组的方式。

    将对象以树形结构组织起来,以达成“部分-整体” 的层次结构,使得客户端对单个对象和组合对象的使用具有一致性.

    2、示例代码

    类图:

    image-20200723174642222

    类的一览表

    image-20200723174657528

    定义Entry类

     package cn.design.structured.compposite;
     
     /**
      * @author lin
      * @version 1.0
      * @date 2020-07-23 17:04
      * @Description TODO
      */
     public abstract class Entry {
         /**
          * 获取名字
          *
          * @return String
          */
         public abstract String getName();
     
         /**
          * 获取大小
          *
          * @return int
          */
         public abstract int getSize();
     
         /**
          * 加入目录条目
          *
          * @param entry 入参
          * @return 返回
          */
         public Entry add(Entry entry) {
             throw new FileTreatmentException();
        }
     
         public void printList() {            // 显示目录条目
             printList("");
        }
     
         protected abstract void printList(String prefix);  // 显示条目前缀
     
         @Override
         public String toString() {
             return getName() + "(" + getSize() + ")";
        }
     }
     

    定义FileTreatmentException类

     package cn.design.structured.compposite;
     
     /**
      * @author lin
      * @version 1.0
      * @date 2020-07-23 17:06
      * @Description TODO
      */
     public class FileTreatmentException extends RuntimeException {
         public FileTreatmentException() {
        }
     
         public FileTreatmentException(String message) {
             super(message);
        }
     
     }
     

    定义File类

     package cn.design.structured.compposite;
     
     /**
      * @author lin
      * @version 1.0
      * @date 2020-07-23 17:05
      * @Description 文件类
      */
     public class File extends Entry {
         private String name;
         private int size;
     
         public File(String name, int size) {
             this.name = name;
             this.size = size;
        }
     
         @Override
         public String getName() {
             return name;
        }
     
         @Override
         public int getSize() {
             return size;
        }
     
         @Override
         protected void printList(String prefix) {
             System.out.println(prefix + "/" + this);
        }
     }
     

    定义Directory类

     package cn.design.structured.compposite;
     
     import java.util.ArrayList;
     import java.util.Iterator;
     
     /**
      * @author lin
      * @version 1.0
      * @date 2020-07-23 17:05
      * @Description TODO
      */
     public class Directory extends Entry {
     
         private final String name;
         private final ArrayList<Entry> directory = new ArrayList<>();
     
         public Directory(String name) {
             this.name = name;
        }
     
         @Override
         public String getName() {
             return name;
        }
     
         @Override
         public int getSize() {
             int size = 0;
             for (Entry entry : directory) {
                 size += entry.getSize();
            }
             return size;
        }
     
         @Override
         protected void printList(String prefix) {
             System.out.println(prefix + "/" + this);
             for (Entry entry : directory) {
                 entry.printList(prefix + "/" + name);
            }
        }
     
         @Override
         public Entry add(Entry entry) {
             directory.add(entry);
             return this;
        }
     }
     

    定义CompositeMain测试类

     package cn.design.structured.compposite;
     
     /**
      * @author lin
      * @version 1.0
      * @date 2020-07-23 16:40
      * @Description TODO
      */
     public class CompositeMain {
         public static void main(String[] args) {
             try {
                 System.out.println("Making root entries............");
                 Entry rooter = new Directory("root");
                 Entry binder = new Directory("bin");
                 Entry teador = new Directory("tmp");
                 Entry under = new Directory("usr");
                 rooter.add(binder);
                 rooter.add(teador);
                 rooter.add(under);
                 binder.add(new File("yi", 1000));
                 binder.add(new File("latex", 200000));
     
                 System.out.println("");
                 System.out.println("Making user entries......");
                 Entry yuki = new Directory("yuki");
                 Entry hanako = new Directory("tomura");
                 Entry tomuura = new Directory("tomura");
                 under.add(yuki);
                 under.add(hanako);
                 under.add(tomuura);
                 yuki.add(new File("diary.html", 1000));
                 rooter.printList();
            } catch (Exception e) {
                 System.err.println();
            }
        }
     }
     

    运行结果如下:

     Making root entries............
     
     Making user entries......
     /root(202000)
     /root/bin(201000)
     /root/bin/yi(1000)
     /root/bin/latex(200000)
     /root/tmp(0)
     /root/usr(1000)
     /root/usr/yuki(1000)
     /root/usr/yuki/diary.html(1000)
     /root/usr/tomura(0)
     /root/usr/tomura(0)
     与目标VM断开连接, 地址为: ''127.0.0.1:54150', transport: '套接字'', 传输: '{1}'
     
     Process finished with exit code 0
     

    3、深入了解

    复合模式类图

    image-20200723174951649

    角色分工

    ◆Leaf(树叶)

    表示“内容”的角色。在该角色中不能放入其他对象。在示例程序中,由File类扮演此角色。

    ◆Composite (复合物)

    表示容器的角色。可以在其中放入Leaf角色和Composite角色。在示例程序中,由 Di rectory类扮演此角色。

    ◆Component

    使Leaf角色和Composite角色具有-致性的角色。Composite 角色是Leaf角色和Composite角 色的父类。在示例程序中,由Entry类扮演此角色。

    ◆Client

    使用Composite模式的角色。在示例程序中,由Main类扮演此角色。 Composite模式的类图如图11-3 所示。在该图中,可以将Composite角色与它内部的 Component角色(即Leaf角色或Composite角色)看成是父亲与孩子们的关系。getChild方法的作用是从Component角色获取这些“孩子们”。

    4、小结

    Composite比较容易理解,想到Composite就应该想到树形结构图。组合体内这些对象都有共同接口,当组合体一个对象的方法被调用执行时,Composite将遍历(Iterator)整个树形结构,寻找同样包含这个方法的对象并实现调用执行。可以用牵一动百来形容。

    意图:将对象组合成树形结构以表示"部分-整体"的层次结构。组合模式使得用户对单个对象和组合对象的使用具有一致性。

    主要解决:它在我们树型结构的问题中,模糊了简单元素和复杂元素的概念,客户程序可以像处理简单元素一样来处理复杂元素,从而使得客户程序与复杂元素的内部结构解耦。

    何时使用: 1、您想表示对象的部分-整体层次结构(树形结构)。 2、您希望用户忽略组合对象与单个对象的不同,用户将统一地使用组合结构中的所有对象。

    如何解决:树枝和叶子实现统一接口,树枝内部组合该接口。

    关键代码:树枝内部组合该接口,并且含有内部属性 List,里面放 Component。

    优点: 1、高层模块调用简单。 2、节点自由增加。

    缺点:在使用组合模式时,其叶子和树枝的声明都是实现类,而不是接口,违反了依赖倒置原则。

    使用场景:部分、整体场景,如树形菜单,文件、文件夹的管理。

    注意事项:定义时为具体类。

    公众号发哥讲

    这是一个稍偏基础和偏技术的公众号,甚至其中包括一些可能阅读量很低的包含代码的技术文,不知道你是不是喜欢,期待你的关注。

    代码分享

    https://gitee.com/naimaohome

    微信公众号 点击关于我,加入QQ群,即可获取到代码以及高级进阶视频和电子书!!

    img

    如果你觉得文章还不错,就请点击右上角选择发送给朋友或者转发到朋友圈~

    ● 扫码关注我们

    据说看到好文章不推荐的人,服务器容易宕机!

    本文版权归 发哥讲博客园 共有,原创文章,未经允许不得转载,否则保留追究法律责任的权利。

     

     

  • 相关阅读:
    SQLserver 连接+开窗函数+视图+事务
    SQLServer学习笔记系列8
    SQLServer学习笔记系列7
    SQLServer学习笔记系列6
    如何保护.net中的dll文件(防破解、反编译)
    idea项目运行正常,但是类出现红色波浪线
    eclipse出现An internal error occurred during: "Repository registry initialization". Array index out of
    ul列表事件($(this).data('value') 这个是什么意思?)
    vue学习
    两段简单的JS代码防止SQL注入
  • 原文地址:https://www.cnblogs.com/naimao/p/13446389.html
Copyright © 2011-2022 走看看