• Composite模式(组合设计模式)


    Composite 设计模式?

    在计算机的文件系统中,有“文件夹”的概念(在有些操作系统(Linux操作系统)中,也称为“目录”)。文件夹里面既可以放入文件,也可以放入其他文件夹(子文件夹)。在子文件夹中,一样地既可以放入文件,也可以放入子文件夹。可以说,文件夹是形成了一种容器结构、递归结构。

    • 结构模式:能够使容器与内容具有一致性,创造出递归结构的模式就是Composite模式。

    • 关注点:使用Composite模式可以使容器与内容具有一致性,也可以称其为多个和单个的一致性,即将多个对象结合在一起,当作一个对象进行处理。

    理清职责

    • 到处存在的递归结构:
    1. 在视窗系统中,一个窗口可以含有一个子窗口,
      2.在文章的列表中,各列表之间可以相互嵌套,这也是一种递归结构。
      3.将多条计算机命令合并为一条宏命令时,如果使用递归结构实现宏命。
      4.树结构的数据结构都适用Composite模式。
    • 实现:演示文件夹 文件子项之间的层次关系
      名字===================>>>说明
      Entry || 抽象类,用来实现File类和Directory类的一致性
      File || 表示文件的类
      Directory || 表示文件夹的类
      FileTreatementException || 表示向文件中增加Entry时发生的异常的类
      Main || 测试程序行为的类

    • Add()方法的存在位置:

    1. 存在Entry 抛出异常。
    2. 存在Entry 中什么也不做。
    3. 声明在Entry中为抽象方法 不去实现。
    4. 直接定义在Directory类中,但是需要关注类型之间的转换。

    UML

    类图:

    Code

    • Entry

    ···

    public abstract class Entry {

    /**
     * 1. 文件名
     * 2. 文件大小
     * @return
     */
    public abstract String getName();
    public abstract int getSize();
    
    /**
     * Directory  增加条目
     * File 不能增加条目
     */
    public Entry add(Entry entry)throws FileTreatementException{
        throw new FileTreatementException();
    }
    
    public void printList(){
        printList("");
    }
    
    protected abstract void printList(String prefix);
    
    @Override
    public String toString() {
        return getName()+"("+getSize()+")";
    }
    

    }

    ···

    • File
    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
    
    public class Directory extends Entry {
    
        private String name;
    
        private List<Entry> directory=new ArrayList<>();
    
        public Directory(String name) {
            this.name = name;
        }
    
        @Override
        public Entry add(Entry entry) throws FileTreatementException {
            directory.add(entry);
            return this;
        }
    
        @Override
        public String getName() {
            return name;
        }
    
        /**
         * getSize() | printList(String prefix)
         *
         * 都会递归去遍历下面可能存在的 目录或者文件的子项
         */
    
        @Override
        public int getSize() {
            int size=0;
            Iterator<Entry> it = directory.iterator();
            while (it.hasNext()){
                // 这里的Entry 可能是目录 也可能是文件
                Entry next = it.next();
                size+=next.getSize();
            }
    
            return size;
        }
    
        @Override
        protected void printList(String prefix) {
            // 这里的 prefix是一个引用 this将会调用tostring()方法 又会继续调用getName() getSize()方法
            System.out.println(prefix+"/"+this);
            Iterator<Entry> it = directory.iterator();
            while(it.hasNext()){
                // 这里的Entry 可能是目录 也可能是文件
                Entry next = it.next();
                next.printList(prefix+"/"+this);
            }
        }
    }
    
    
    
    
    • FileTreatementException
    
    public class FileTreatementException extends Exception {
    
        public FileTreatementException() {
        }
    
        public FileTreatementException(String message) {
            super(message);
        }
    }
    
    
    
    • 定义的目的结构:
    start +++++++++++
    /root(16000)
    /root(16000)/bin(16000)
    /root(16000)/bin(16000)/vi(1000)
    /root(16000)/bin(16000)/notepaid(15000)
    /root(16000)/temp(0)
    /root(16000)/user(0)
    
    
    • MainT
    public class MainT {
    
        public static void main(String[] args) throws FileTreatementException{
    
            System.out.println("start +++++++++++");
    
            Directory rootdir=new Directory("root");
    
            Directory bindir = new Directory("bin");
            Directory tempdir = new Directory("temp");
            Directory userdir = new Directory("user");
    
            rootdir.add(bindir);
            rootdir.add(tempdir);
            rootdir.add(userdir);
    
            bindir.add(new File("vi",1000));
            bindir.add(new File("notepaid",15000));
    
            rootdir.printList();
        }
    }
    
    
  • 相关阅读:
    NodeJS优缺点
    移动端触摸相关事件touch、tap、swipe
    vscode使用技巧
    js 字符串转数字
    js 导出Excel
    <!--[if IE 9]> <![endif]-->
    js 异步请求
    关于windows串口处理
    mfc 托盘提示信息添加
    微软的麦克风处理示列代码
  • 原文地址:https://www.cnblogs.com/dgwblog/p/9840291.html
Copyright © 2020-2023  润新知