设计模式之组合模式

设计模式之组合模式
  1. 需求

    1. 看一个学校院系展示需求:编写一个程序展示一个学校院系结构:要在一个页面中展示出学校的页面组成。一个学校有多个学院,一个学院有的多个系,如图:

       

  2. 传统方式解决:就是系继承学院,学院继承学校(但是学校和学院、学院和系之间应该是包含关系)

    1. 传统方案解决学校院系展示问题分析

      1. 将学院看做学校的子类,系是学院的子类,这样实际上是站在组织大小来进行分层次的

      2. 实际上我们的要求是:在一个页面中展示出学校的院系组成,一个学校有多少个院,一个院都多少个系,因此这种方案,不能很好的实现管理的操作,例如对院系的增删改查

      3. 解决方案:吧学校、院、系都看成组织结构,他们之间是没有继承关系的而是一个树形结构,这样可以更好的实现管理操作 ====》组合模式

  3. 组合模式

    1. 基本介绍

      1. 组合模式又叫部分整体模式,它创建的对象组的树形结构,将对象组合成树状结构以表示“整体-部分”的层次关系

      2. 组合模式依据树形结构来组合对象,用来表示部分以及整体的层次

      3. 这种类型的设计模式数据结构者模式

      4. 组合模式使得用户对单个对象和组合对象的访问具有一致性,即:组合能让客户以一致的方式处理个别对象以及组合对象

    2. 组合模式原理类图

    3. 组合模式原理分析(组合模式的角色及职责)

      1. Component:这是组合中的一个对象声明接口,在适当的情况下,实现所有类共有的接口默认行为,用于访问和管理Component子部件,可以是抽象类或者接口

      2. Leaf:在组合模式中表示叶子节点,

      3. Composite:非叶子节点,用于存储子部件,在Component接口中实现子部件的相关操作,比如增加、删除等操作

    4. 组合模式解决的问题

      1. 组合模式解决这样的问题,当我们要处理的对象可生成一个树形结构而我们要对树上的节点进行操作时,他能够提供一致的方式,而不用考虑其他节点

      2. 示意图

      3. 使用组合模式解决院校展示问题

        1. 类图

        2. 代码实现

          //编写一个抽象类
          public abstract class OrganizationComponent{
             private String name;
             private String des;//描述
             //get和set方法
             //全全参构造器
             protected void add(OrganizationComponent organizationComponent ){
                 //在抽象中实现这个方法的原因就是系是一个叶子节点,如果写成抽象方法,则叶子节点需要实现,不太合适
                 throw new UnsupportedOperationException();
            }
             protected void remove(OrganizationComponent organizationComponent ){
                 //在抽象中实现这个方法的原因就是系是一个叶子节点,如果写成抽象方法,则叶子节点需要实现,不太合适
                 throw new UnsupportedOperationException();
            }    
             public abstract void print();
          }

          //就是composite,可以管理College
          public class University extends OrganizationComponent{
             Lsit<OrganizationComponent> organizationComponents = new ArrayList();
             public University(String name,String des){
                 super(name,des);
            }
             @Override
             public String getName(){
                 return super.getName();
            }
             @Override
             public String getDes(){
                 return super.getDes();
            }
             
             //重写add
             @Override
             protected  void add(OrganizationComponent organizationComponent){
                 organizationComponents.add(organizationComponent);
            }
             
              //重写remove
             @Override
             protected  void add(OrganizationComponent organizationComponent){
                 organizationComponents.remove (organizationComponent);
            }
             @Override
             //输出包含的学院
             public void print(){
                 //输出学校的名字
                 System.out.println("----------"+getName()+"----------------------");
                 //遍历organizationComponents
                 for(OrganizationComponent organizationComponent:organizationComponents){
                     organizationComponent.print();
                }
                     
            }
             
             
          }

          //编写college
          public class College extends organizationComponent{
             //存储的是具体的系 department
             Lsit<OrganizationComponent> organizationComponents = new ArrayList();
             public College(String name,String des){
                 super(name,des);
            }
             @Override
             public String getName(){
                 return super.getName();
            }
             @Override
             public String getDes(){
                 return super.getDes();
            }
             //重写add
             @Override
             protected  void add(OrganizationComponent organizationComponent){
                 organizationComponents.add(organizationComponent);
            }
             
              //重写remove
             @Override
             protected  void add(OrganizationComponent organizationComponent){
                 organizationComponents.remove (organizationComponent);
            }
             @Override
             //输出包含的系
             public void print(){
                 //输出学校的名字
                 System.out.println("----------"+getName()+"----------------------");
                 //遍历organizationComponents
                 for(OrganizationComponent organizationComponent:organizationComponents){
                     organizationComponent.print();
                }
                     
            }    
          }

          //Department
          public class Department extends OrganizationComponent{
             public Department(){
                 super(name,des);
            }
             @Override
             public String getName(){
                 return super.getName();
            }
             @Override
             public String getDes(){
                 return super.getDes();
            }  
             @Override
             public void print(){
                 System.out.println(getName())
            }
          }

          //Client
          public class Client{
             public static void main(String[] args){
                 //按照从大到小操作
                 //创建学校
                 OrganizationComponent university = new University("清华大学";"中国的顶尖大学");
                 //创建学院
                 OrganizationComponent computercollege = new College("信息工程学院""计算机王牌学院");
                 OrganizationComponent wulicollege = new College("物理学院""特色学院");
                 //创建各个学院下面的系
                 computercollege.add(new Department("计算机科学与技术","王牌专业");
                 computercollege.add(new Department("信息安全","新型专业") ;
                 computercollege.add(new Department("网络安全专业","优势学科");
                 wulicollege.add(new Department("力学","王牌专业");
                 wulicollege.add(new Department("电磁学","优势专业");      
                                 
                 university.add(computercollege);  
                 university.add(wulicollege);
                                 
                  university.print();
                                     
            }
          }

           

  4. 组合模式在JDK源码中的应用

    1. java的集合类HashMap就使用了组合模式

    2. 代码

      public class Test{
         public static void main(String[] args){
             //Map就是一个抽象的构建(类似一个Component)
             //HashMap是一个中间构建(Composite),实现了相关方法putputAll等
             //Node是HashMap的一个静态内部类,类似一个叶子节点
             Map<Integer,String> hashMap = new HashMap();
             hashMap.put(0,"西游记");//直接存放叶子节点
             Map<Integer,String> map = new HashMap();
             map.put(1,"红楼梦");
             map.put(2,"三国演义");
             hashMap.putAll(map);
             System.out.println(hashMap)
        }
      }
  5. 组合模式注意事项

    1. 简化客户端操作。客户端只需要面对一致的对象而不用考虑整体部分或者节点叶子的问题

    2. 具有较强的扩展性。当需要更改组合对象时,只需要调整内部的层次关系,客户端不用做任何改动

    3. 方便构造出复杂的层次结构。客户端不用理会组合里面的组成细节,容易添加节点或者叶子从而创建出更复杂的树形接口

    4. 主要遍历组织机构,如果处理的对象具有树形结构时,非常适合使用组合模式

    5. 要求较高的抽象性,如果节点和叶子具有较高的差异性的话,比如很多方法和属性都不一样,则不适合使用组合模式

原文地址:https://www.cnblogs.com/juddy/p/14995365.html