美文网首页
设计模式-组合模式

设计模式-组合模式

作者: 蜗牛写java | 来源:发表于2019-12-16 21:59 被阅读0次

    设计模式-组合模式

    概念

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

    组合模式也叫合成模式,有时也叫部分-整体模式;主要用来描述部分与整体的关系

    类型:结构型

    使用场景

    • 忽略单个对象和组合对象时
    • 树状结构、层级结构等;如:公司组织架构、书籍目录、树形菜单

    优点

    • 清楚地定义分层次的复杂对象,表示对象的全部或部分层次
    • 简化客户端代码,忽略层次差异,方便对整个层次结构进行控制
    • 高层模块调用简单、节点自由增加

    缺点

    • 限制类型会复杂(因为部分与整体具有使用一执行)
    • 设计变得抽象

    UML

    组合模式UML.png
    • Component:抽象构建角色

      定义参加组合独享的共有方法和属性

      public abstract class Component {
        //个体和整体都具有的行为
        public abstract void operate() {
          //抽象方法
        }
        public abstract void add(Component component) {}
        
        public abstract void remove(Component component) {}
      }
      
    • Composite:树枝构件

      树枝对象,作用是组合树枝节点和叶子节点形成一个属性结构

      public class Composite extends Component {
        //构建容器
        private List<Component> components = new ArrayList<>();
        //增加一个叶子构件或者树枝构件
        public void add(Component component) {
          this.components.add(component);
        }
        //删除一个叶子节点
        public void remove(Component component) {
          this.components.remove(component);
        }
        //操作
        public void operate() {
          for (Component component : components) {
            component.operate();
          }
        }
        
      }
      
    • Left:叶子构件

      叶子对象,组合模式中的最小单位

      public class Leaf extends Component {
        //具体操作
        public void operate() {
          //...
        }
      }
      

    实例

    我们以《深入理解Java虚拟机》这本书的目录为例

    UML


    组合实例UML.png

    抽象构件角色

    /**
     * 书本目录
     */
    public class CatalogComponent {
    
        //名称
        private String name;
        //页码
        private int page;
    
        public CatalogComponent(String name, int page) {
            this.name = name;
            this.page = page;
        }
    
        public void add(CatalogComponent catalogComponent) {
            throw new UnsupportedOperationException("不支持添加操作!");
        }
    
        public void remove(CatalogComponent catalogComponent) {
            throw new UnsupportedOperationException("不支持删除操作!");
        }
    
        public void list() {
            throw new UnsupportedOperationException("不支持列表操作!");
        }
    
        @Override
        public String toString() {
            return super.toString();
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public int getPage() {
            return page;
        }
    
        public void setPage(int page) {
            this.page = page;
        }
    }
    

    数据构件

    public class ChapterCatalog extends CatalogComponent {
    
        private List<CatalogComponent> chapters = new ArrayList<>();
    
        public ChapterCatalog(String name, int page) {
            super(name, page);
        }
    
        @Override
        public void add(CatalogComponent catalogComponent) {
            chapters.add(catalogComponent);
        }
    
        @Override
        public void remove(CatalogComponent catalogComponent) {
            chapters.remove(catalogComponent);
        }
    
        @Override
        public String toString() {
            return this.getName() + "---------" + this.getPage();
        }
    
        @Override
        public void list() {
            System.out.println(this.toString());
            for (CatalogComponent chapter : chapters) {
                if (chapter instanceof ChapterCatalog) {
                    chapter.list();
                } else {
                    System.out.println("    " + chapter.toString());
                }
            }
        }
    }
    

    叶子构件

    public class Chapter extends CatalogComponent {
    
        public Chapter(String name, int page) {
            super(name, page);
        }
    
        @Override
        public String toString() {
            return this.getName() + "---------" + this.getPage();
    
        }
    }
    

    使用场景

    /**
     * 我们以深入理解Java虚拟机为例;只做两层目录demo
     */
    public class Client {
    
        public static void main(String[] args) {
    
            CatalogComponent javaJvmBook = new ChapterCatalog("深入理解Java虚拟机",0);
    
            CatalogComponent firstChapterCatalog = new ChapterCatalog("走进java", 2);
            CatalogComponent firstChapterOne = new Chapter("概述", 2);
            CatalogComponent firstChapterTwo = new Chapter("java技术体系", 5);
            CatalogComponent firstChapterThree = new Chapter("java虚拟机发展史", 9);
            firstChapterCatalog.add(firstChapterOne);
            firstChapterCatalog.add(firstChapterTwo);
            firstChapterCatalog.add(firstChapterThree);
    
            CatalogComponent secondChapterCatalog = new ChapterCatalog("java内存区域与内存溢出异常", 38);
            CatalogComponent secondChapterOne = new Chapter("概述", 38);
            CatalogComponent secondChapterTwo = new Chapter("运行时数据区域", 38);
            CatalogComponent secondChapterThree = new Chapter("HotSpot虚拟机对象探秘", 43);
            secondChapterCatalog.add(secondChapterOne);
            secondChapterCatalog.add(secondChapterTwo);
            secondChapterCatalog.add(secondChapterThree);
    
            CatalogComponent thirdChapterCatalog = new ChapterCatalog("垃圾收集器与内存分配策略", 61);
            CatalogComponent thirdChapterOne = new Chapter("概述", 61);
            CatalogComponent thirdChapterTwo = new Chapter("垃圾收集算法", 62);
            CatalogComponent thirdChapterThree = new Chapter("垃圾收集器", 69);
            thirdChapterCatalog.add(thirdChapterOne);
            thirdChapterCatalog.add(thirdChapterTwo);
            thirdChapterCatalog.add(thirdChapterThree);
    
            javaJvmBook.add(firstChapterCatalog);
            javaJvmBook.add(secondChapterCatalog);
            javaJvmBook.add(thirdChapterCatalog);
    
            javaJvmBook.list();
        }
    }
    

    输出:

    深入理解Java虚拟机---------0
    走进java---------2
    概述---------2
    java技术体系---------5
    java虚拟机发展史---------9
    java内存区域与内存溢出异常---------38
    概述---------38
    运行时数据区域---------38
    HotSpot虚拟机对象探秘---------43
    垃圾收集器与内存分配策略---------61
    概述---------61
    垃圾收集算法---------62
    垃圾收集器---------69

    相关文章

      网友评论

          本文标题:设计模式-组合模式

          本文链接:https://www.haomeiwen.com/subject/nykjnctx.html