zoukankan      html  css  js  c++  java
  • 学习设计模式之组合模式

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

    类结构图
    在这里插入图片描述
    Component
    组合中的对象声明接口,在适当情况下,实现所有类共有的接口默认行为。声明一个接口用于访问和管理 Component 的子部件。
    Composite
    定义节点的行为,用来存储子部件,在 Component 接口中实现与子部件有关的操作,比如增加 add 和删除 remove。
    Leaf
    在组合中表示叶节点对象,叶节点没有子节点。

    树结构的例子有很多,文件、公司、菜单的结构。下面我们就用文件的例子来看看。

    代码实现

    public interface IFile {
        void delete();
    
        String getName();
    
        void newFile(String name);
    
        void delFile(String name);
    
        IFile getFile(int index);
    }
    
    public class Folder implements IFile {
    
        private String name;
        private IFile folder;
        private List<IFile> files;
    
        public Folder(String name) {
            this(name, null);
        }
    
        public Folder(String name, IFile folder) {
            this.name = name;
            this.folder = folder;
            files = new ArrayList<>();
        }
    
        @Override
        public String getName() {
            return this.name;
        }
    
        @Override
        public void delete() {
            Iterator<IFile> iterator = files.iterator();
            while (iterator.hasNext()) {
                iterator.remove();
            }
            System.out.println(">>>>>>>> 删除子文件结束 <<<<<<<<<<");
            if (null != this.folder) {
                this.folder.delFile(this.name);
            }
            System.out.println(">>>>>>>> 删除 " + this.name + " 结束 <<<<<<<<<<");
        }
    
        @Override
        public void newFile(String name) {
            if (name.contains(".")) {
                files.add(new File(name, this));
            } else {
                files.add(new Folder(name, this));
            }
        }
    
        @Override
        public void delFile(String name) {
            Iterator<IFile> iterator = files.iterator();
            while (iterator.hasNext()) {
                IFile file = iterator.next();
                if (file.getName().equals(name)) {
                    iterator.remove();
                }
            }
        }
    
        @Override
        public IFile getFile(int index) {
            return this.files.get(index);
        }
    }
    
    public class File implements IFile {
    
        private String name;
        private IFile folder;
    
        public File(String name, IFile folder) {
            this.name = name;
            this.folder = folder;
        }
    
        @Override
        public String getName() {
            return this.name;
        }
    
        @Override
        public void delete() {
            this.folder.delFile(this.name);
            System.out.println(">>>>>>>>>> 删除 " + this.name + " <<<<<<<<<<");
        }
    
        @Override
        public void newFile(String name) {
            System.out.println(">>>>>>>>>> 不支持创建新文件 <<<<<<<<<<");
        }
    
        @Override
        public void delFile(String name) {
            System.out.println(">>>>>>>>>> 不支持删除子文件 <<<<<<<<<<");
        }
    
        @Override
        public IFile getFile(int index) {
            System.out.println(">>>>>>>>>> 不支持获取子文件 <<<<<<<<<<");
            return null;
        }
    }
    

    客户端示例

    public class Client {
        public static void main(String[] args) {
            IFile root = new Folder("root 文件");
            root.newFile("1 文件");
            root.newFile("2 文件");
            root.newFile("3 文件");
    
            IFile c = root.getFile(0);
            c.newFile("Program Files");
            IFile program = c.getFile(0);
            program.newFile("怎么学习设计模式.pdf");
    
            IFile d = root.getFile(1);
            d.newFile("学习学籍");
            IFile pdfs = d.getFile(0);
            pdfs.newFile("agile java.pdf");
            pdfs.newFile("Effective Java 中文第二版.pdf");
            pdfs.newFile("Java8实战.pdf");
    
            showFiles(root);
        }
    
        private static final void showFiles(IFile iFile) {
            showFiles(null, iFile);
        }
    
        private static final void showFiles(String prefix, IFile iFile) {
            if (null == prefix) {
                prefix = "";
            }
            System.out.println(prefix + iFile.getName());
            if (iFile instanceof Folder) {
                for (int i = 0; ; i++) {
                    try {
                        if (iFile.getFile(i) != null) {
                            showFiles(prefix + "--", iFile.getFile(i));
                        }
                    } catch (Exception e) {
                        break;
                    }
                }
            }
        }
    }
    

    运行结果

    root 文件
    --1 文件
    ----Program Files
    ------怎么学习设计模式.pdf
    --2 文件
    ----学习学籍
    ------agile java.pdf
    ------Effective Java 中文第二版.pdf
    ------Java8实战.pdf
    --3 文件
    
    Process finished with exit code 0
    

    使用场景
    当发现需求中是体现部分与整体层级的结构时,以及你希望用户可以忽略组合对象与单个对象的不同,统一地使用结构中的所有对象时,就应该考虑使用组合模式了。

    优点

    1. 组合模式使得客户端代码可以一致地处理对象和对象容器,无需关系处理的单个对象,还是组合的对象容器。
    2. 将”客户代码与复杂的对象容器结构“解耦。
    3. 可以更容易地往组合对象中加入新的构件。

    缺点

    使得设计更加复杂。客户端需要花更多时间理清类之间的层次关系。

    勿在浮沙筑高台 ——个人浅见,难免有误导之处,麻烦请指出。
  • 相关阅读:
    Ubuntu下下载Android源码
    升级Android 3.1ADT 和SDK
    ubuntu10.04手动安装jdk1.6.0_24配置
    安装VM Tools
    Singleton (单件模式)
    biztalk2004安装时应该注意的几点
    欢迎高手加入.NET技术群
    Observer(观察者模式)
    无眠
    A⑤权限管理分配权限:提交的是节点的id列表
  • 原文地址:https://www.cnblogs.com/liufeichn/p/11961641.html
Copyright © 2011-2022 走看看