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)…………

  • 相关阅读:
    高级特性(4)- 数据库编程
    UVA Jin Ge Jin Qu hao 12563
    UVA 116 Unidirectional TSP
    HDU 2224 The shortest path
    poj 2677 Tour
    【算法学习】双调欧几里得旅行商问题(动态规划)
    南洋理工大学 ACM 在线评测系统 矩形嵌套
    UVA The Tower of Babylon
    uva A Spy in the Metro(洛谷 P2583 地铁间谍)
    洛谷 P1095 守望者的逃离
  • 原文地址:https://www.cnblogs.com/cao-lei/p/8327693.html
Copyright © 2011-2022 走看看