zoukankan      html  css  js  c++  java
  • GOF23设计模式之组合模式(composite)

    一、组合模式概述

      将对象组合成树状结构以表示“部分和整体”层次结构,使得客户可以统一的调用叶子对象和容器对象。

      (1)组合模式的使用场景

          把部分和整体的关系用树形结构来表示,从而使客户端可以使用统一的方式处理部分对象和整体对象。

      (2)组合模式核心

          抽象构件(Component)角色:定义了叶子和容器构件的共同点

          叶子(Leaf)构件角色:无子节点

          容器(Composite)构件角色:有容器特征,可以包含子节点

     1 /**
     2  * 抽象组件
     3  * @author CL
     4  *
     5  */
     6 public interface Component {
     7     void operation();
     8 }
     9 
    10 /**
    11  * 叶子组件
    12  * @author CL
    13  *
    14  */
    15 interface Leaf extends Component {
    16 }
    17 
    18 /**
    19  * 容器组件
    20  * @author CL
    21  *
    22  */
    23 interface Composite extends Component {
    24     void add(Component c);
    25     void remove(Component c);
    26     Component getChild(int index);
    27 }

    二、组合模式工作流程分析

      (1)组合模式为处理树形结构提供了完美的解决方案,描述了如何将容器和叶子进行递归组合,使得用户在使用时可以一致性的对待容器和叶子。

      (2)当容器对象的指定方法被调用时,将遍历整个树形结构,寻找也包含这个方法的成员,并调用执行。其中,使用了递归调用的机制对整个结构进行处理。

    三、使用组合模式模拟杀毒软件架构设计

      1 import java.util.ArrayList;
      2 import java.util.List;
      3 
      4 /**
      5  * 模拟杀毒软软件架构设计
      6  * 抽象组件
      7  * @author CL
      8  *
      9  */
     10 public interface AbstractFile {
     11     /**
     12      * 杀毒
     13      */
     14     void killVirus();
     15 }
     16 
     17 /**
     18  * 对图片文件进行杀毒
     19  * @author CL
     20  *
     21  */
     22 class ImageFile implements AbstractFile {
     23     private String name;
     24 
     25     public ImageFile(String name) {
     26         this.name = name;
     27     }
     28 
     29     @Override
     30     public void killVirus() {
     31         System.out.println("-->对图像文件""+name+""进行查杀!");
     32     }
     33     
     34 }
     35 
     36 /**
     37  * 对文本文件进行杀毒
     38  * @author CL
     39  *
     40  */
     41 class TxtFile implements AbstractFile {
     42     private String name;
     43 
     44     public TxtFile(String name) {
     45         this.name = name;
     46     }
     47 
     48     @Override
     49     public void killVirus() {
     50         System.out.println("-->对文本文件""+name+""进行查杀!");
     51     }
     52     
     53 }
     54 
     55 /**
     56  * 对视频文件进行杀毒
     57  * @author CL
     58  *
     59  */
     60 class VideoFile implements AbstractFile {
     61     private String name;
     62 
     63     public VideoFile(String name) {
     64         this.name = name;
     65     }
     66 
     67     @Override
     68     public void killVirus() {
     69         System.out.println("-->对视频文件""+name+""进行查杀!");
     70     }
     71     
     72 }
     73 
     74 /**
     75  * 容器组件
     76  * @author CL
     77  *
     78  */
     79 class Folder implements AbstractFile {
     80     private String name;
     81     //容器:用来存放容器构建下的子节点
     82     private List<AbstractFile> list;
     83     
     84     public Folder() {
     85         list = new ArrayList<AbstractFile>();
     86     }
     87     
     88     public Folder(String name) {
     89         this();
     90         this.name = name;
     91     }
     92 
     93     public void add(AbstractFile file) {
     94         list.add(file);
     95     }
     96     
     97     public void remove(AbstractFile file) {
     98         list.remove(file);
     99     }
    100     
    101     public AbstractFile getChild(int index) {
    102         return list.get(index);
    103     }
    104 
    105     @Override
    106     public void killVirus() {
    107         System.out.println("-->文件夹""+name+""进行查杀!");
    108         
    109         for (AbstractFile file : list) {
    110             file.killVirus();    //递归
    111         }
    112     }
    113     
    114 }

      测试:

     1 /**
     2  * 使用组合模式模拟杀毒软件
     3  * @author CL
     4  *
     5  */
     6 public class Client {
     7 
     8     public static void main(String[] args) {
     9         //1. 将图片和文件加入到文件夹中,对文件夹进行查杀
    10         Folder f1 = new Folder("我的文档");
    11         AbstractFile f2, f3, f4, f5;
    12         
    13         f2 = new ImageFile("xaau.jpg");
    14         f3 = new TxtFile("Hello.java");
    15         f1.add(f2);
    16         f1.add(f3);
    17         
    18         f1.killVirus();
    19         
    20         System.out.println("-----------------------------------");
    21         
    22         //2.在文件夹中再加入一个文件夹,其中包含两个视频文件
    23         Folder f11 = new Folder("电影");
    24         f4 = new VideoFile("宝贝计划.avi");
    25         f5 = new VideoFile("泰囧.avi");
    26         f11.add(f4);
    27         f11.add(f5);
    28         
    29         f1.add(f11);
    30         //对文件夹进行递归查杀
    31         f1.killVirus();
    32     }
    33 }

      控制台输出:

    -->文件夹"我的文档"进行查杀!
    -->对图像文件"xaau.jpg"进行查杀!
    -->对文本文件"Hello.java"进行查杀!
    -----------------------------------
    -->文件夹"我的文档"进行查杀!
    -->对图像文件"xaau.jpg"进行查杀!
    -->对文本文件"Hello.java"进行查杀!
    -->文件夹"电影"进行查杀!
    -->对视频文件"宝贝计划.avi"进行查杀!
    -->对视频文件"泰囧.avi"进行查杀!

    四、组合模式常用开发应用场景

      (1)操作系统的资源管理器;

      (2)GUI的容器层次图;

      (3)XML文件解析;

      (4)OA系统中,组织结构的处理;

      (5)Junit单元测试框架

          底层设计就是典型的组合模式,TestCase(叶子)、TestUnite(容器)、Test(抽象)

      (6)…………

  • 相关阅读:
    ubuntu11.04安装NetBeans 7.0中文显示乱码或者方框问题的解决(JRE中文字体设置)
    我在CSDN上的博客地址!
    ubuntu11.04手工安装flash插件
    漫谈ubuntu 的安装,兼论操作系统安装方式的进步!
    ubuntu 11.04下android开发环境的搭建!
    网络流24题(09)方格取数问题(最大点权独立集 + 最小割最大流)
    POJ 3273 Monthly Expense(二分搜索巧妙利用)
    网络流24题(10)餐巾计划问题(最小费用最大流)
    网络流24题(05)魔术球问题(最小路径覆盖 + 最大流)
    网络流24题(06)最长递增子序列问题(最多不相交路径 + 最大流)
  • 原文地址:https://www.cnblogs.com/cao-lei/p/8327693.html
Copyright © 2011-2022 走看看