ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

GOF设计模式(08)组合模式

2019-08-14 16:08:13  阅读:218  来源: 互联网

标签:name 08 GOF AbstractFile add void 构件 设计模式 public


简介

一、定义

  • 组合(Composite)模式:组合多个对象形成树形结构以表示具有“整体-部分”关系的层次结构。
  • 组合模式对单个对象(即叶子对象)和组合对象(即容器对象)的使用具有一致性,组合模式又可以称为“部分-整体”(Part-Whole)模式,它是一种对象结构型模式。

二、组件

  • Component(抽象构件):它可以是接口或抽象类,为叶子构件和容器构件对象声明接口,在该角色中可以包含所有子类共有行为的声明和实现。在抽象构件中定义了访问及管理它的子构件的方法,如增加子构件、删除子构件、获取子构件等。
  • Leaf(叶子构件):它在组合结构中表示叶子节点对象,叶子节点没有子节点,它实现了在抽象构件中定义的行为。对于那些访问及管理子构件的方法,可以通过异常等方式进行处理。
  • Composite(容器构件):它在组合结构中表示容器节点对象,容器节点包含子节点,其子节点可以是叶子节点,也可以是容器节点,它提供一个集合用于存储子节点,实现了在抽象构件中定义的行为,包括那些访问及管理子构件的方法,在其业务方法中可以递归调用其子节点的业务方法。

三、结构图

在这里插入图片描述


示例:文件系统

一、抽象组件

//抽象文件类:抽象构件  
abstract class AbstractFile {  
    public abstract void add(AbstractFile file);  
    public abstract void remove(AbstractFile file);  
    public abstract AbstractFile getChild(int i);  
    public abstract void operation();  
}  

二、叶子组件

  • 在叶子构件中实现子构件管理和访问方法时需要提供异常处理或错误提示
//图像文件类:叶子构件  
class ImageFile extends AbstractFile {  
    private String name;  
      
    public ImageFile(String name) {  
        this.name = name;  
    }  
      
    public void add(AbstractFile file) {  
       System.out.println("对不起,不支持该方法!");  
    }  
      
    public void remove(AbstractFile file) {  
        System.out.println("对不起,不支持该方法!");  
    }  
      
    public AbstractFile getChild(int i) {  
        System.out.println("对不起,不支持该方法!");  
        return null;  
    }  
      
    public void operation() {    
        System.out.println("----对图像文件'" + name + "'进行operation");  
    }  
}  
  
//文本文件类:叶子构件  
class TextFile extends AbstractFile {  
    private String name;  
      
    public TextFile(String name) {  
        this.name = name;  
    }  
      
    public void add(AbstractFile file) {  
       System.out.println("对不起,不支持该方法!");  
    }  
      
    public void remove(AbstractFile file) {  
        System.out.println("对不起,不支持该方法!");  
    }  
      
    public AbstractFile getChild(int i) {  
        System.out.println("对不起,不支持该方法!");  
        return null;  
    }  
      
    public void operation() {  
        System.out.println("----对文本文件'" + name + "'进行operation");  
    }  
}  
  
//视频文件类:叶子构件  
class VideoFile extends AbstractFile {  
    private String name;  
      
    public VideoFile(String name) {  
        this.name = name;  
    }  
      
    public void add(AbstractFile file) {  
       System.out.println("对不起,不支持该方法!");  
    }  
      
    public void remove(AbstractFile file) {  
        System.out.println("对不起,不支持该方法!");  
    }  
      
    public AbstractFile getChild(int i) {  
        System.out.println("对不起,不支持该方法!");  
        return null;  
    }  
      
    public void operation() {      
        System.out.println("----对视频文件'" + name + "'进行operation");  
    }  
}

三、容器组件

  • 由于容器构件中仍然可以包含容器构件,因此在对容器构件进行处理时需要使用递归算法
//文件夹类:容器构件  
class Folder extends AbstractFile {  
    //定义集合fileList,用于存储AbstractFile类型的成员  
    private ArrayList<AbstractFile> fileList=new ArrayList<AbstractFile>();  
    private String name;  
          
    public Folder(String name) {  
        this.name = name;  
    }  
      
    public void add(AbstractFile file) {  
       fileList.add(file);    
    }  
      
    public void remove(AbstractFile file) {  
        fileList.remove(file);  
    }  
      
    public AbstractFile getChild(int i) {  
        return (AbstractFile)fileList.get(i);  
    }  
      
    public void killVirus() {  
        System.out.println("****对文件夹'" + name + "'进行杀毒");  //模拟杀毒  
          
        //递归调用成员构件的operation()方法  
        for(Object obj : fileList) {  
            ((AbstractFile)obj).operation();  
        }  
    }  
} 

四、测试代码

class Client {  
    public static void main(String args[]) {  
        //针对抽象构件编程  
        AbstractFile file1,file2,file3,file4,file5,folder1,folder2,folder3,folder4;  
          
        folder1 = new Folder("Sunny的资料");  
        folder2 = new Folder("图像文件");  
        folder3 = new Folder("文本文件");  
        folder4 = new Folder("视频文件");  
          
        file1 = new ImageFile("小龙女.jpg");  
        file2 = new ImageFile("张无忌.gif");  
        file3 = new TextFile("九阴真经.txt");  
        file4 = new TextFile("葵花宝典.doc");  
        file5 = new VideoFile("笑傲江湖.rmvb");  
  
        folder2.add(file1);  
        folder2.add(file2);  
        folder3.add(file3);  
        folder3.add(file4);  
        folder4.add(file5);  
        folder1.add(folder2);  
        folder1.add(folder3);  
        folder1.add(folder4);  
               
        folder1.operation();  
    }  
}

总结

一、优缺点

1、优点

  • 可以清楚地定义分层次的复杂对象,表示对象的全部或部分层次,使客户忽略了层次的差异,方便对整个层次结构进行控制。
  • 增加新的容器构件和叶子构件都十分方便,无需对现有类库代码进行任何修改,符合开闭原则。
  • 为树形结构的面向对象实现提供了灵活地解决方案,可以形成复杂的树形结构,但对树形结构的控制却很简单。

2、缺点

  • 增加新构件时很难对容器中的构建类型进行限制。

二、使用场景

  • 在具有整体和部分的层次结构中,希望通过一种方式忽略整体与部分的差异,客户端可以一致地对待他们。
  • 在一个使用面向对象语言开发的系统中需要处理一个树形结构,文件系统、组织结构等树型结构模型可以使用组合模式。

三、安全组合模式&透明组合模式

1、安全组合模式

  • 讨论这两种模式的前提是叶子组件和容器组件本质上还是存在不同的,叶子组件不可能有 add、remove、getChild 等方法;
  • 安全模式无外乎就是把以上的三个方法定义为容器的特有方法,在抽象组件中不进行定义;
  • 好处就是不存在方法调用的安全问题了,但是这样一来就无法完全面对抽象编程;

2、透明组合模式

  • 就是将叶子和容器统一对待,抽象组件中定义所有方法,会带来安全问题;
  • 一个解决方法是使用时叶子组件声明具体类型,但是抽象度又下来了;

标签:name,08,GOF,AbstractFile,add,void,构件,设计模式,public
来源: https://blog.csdn.net/stanwuc/article/details/99576564

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有