设计模式8之c+组合模式的使用和优化

Posted 小激动. Caim

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了设计模式8之c+组合模式的使用和优化相关的知识,希望对你有一定的参考价值。

组合模式是一种结构型设计模式,它以树形结构来组合对象,以达到表示部分-整体的层次结构,并且可以使客户端统一处理单个对象和组合对象。

在组合模式中,有两种基本类型的对象:叶子节点和组合节点。叶子节点表示不能再被分解的对象,而组合节点表示由若干子节点组成的复杂对象。组合节点可以包含叶子节点和其他组合节点,从而构造出一棵树形结构。

下面是一个使用C++语言实现的组合模式的示例代码:

#include <iostream>
#include <vector>

class Component 
public:
    virtual void operation() = 0;
;

class Leaf: public Component 
public:
    void operation() override 
        std::cout << "Leaf operation." << std::endl;
    
;

class Composite: public Component 
public:
    void add(Component *c) 
        children.push_back(c);
    

    void operation() override 
        std::cout << "Composite operation." << std::endl;
        for (auto child : children) 
            child->operation();
        
    

private:
    std::vector<Component*> children;
;

int main() 
    Composite *root = new Composite;
    Composite *node1 = new Composite;
    Leaf *node2 = new Leaf;
    Leaf *node3 = new Leaf;

    root->add(node1);
    root->add(node2);
    node1->add(node3);

    root->operation();

    delete root;
    delete node1;
    delete node2;
    delete node3;

    return 0;

在上面的代码中,Component是组合模式中的组件类,它包含了一个操作方法operation(),该方法在叶子节点和组合节点中被不同实现。Leaf是叶子节点,实现了operation()方法;Composite是组合节点,它维护一个子节点的列表,并实现了add()operation()方法。

main()函数中,我们创建了一个根节点root、一个组合节点node1和两个叶子节点node2node3。我们首先将node1node2作为root的子节点,然后将node3作为node1的子节点。最后,调用rootoperation()方法,输出整个树形结构的操作结果。

组合模式的优点有:

  1. 组合模式可以清晰、灵活地描述对象的层次结构,方便添加新的组件;
  2. 组合模式使得客户端可以统一处理单个对象和组合对象,避免客户端访问时的复杂判断逻辑;
  3. 组合模式可以使得组合对象和叶子对象具备一致的行为接口。

组合模式的缺点有:

  1. 当组合对象和叶子对象的职责不同时,需要进行类型检查,增加了系统的复杂度;
  2. 对象的子对象不能够自行添加或删除,需要通过父节点来操作。

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

以上是关于设计模式8之c+组合模式的使用和优化的主要内容,如果未能解决你的问题,请参考以下文章

设计模式之组合模式

设计模式学习笔记之组合模式

设计模式之组合模式

Head First设计模式之组合模式

设计模式之组合模式

设计模式之GOF23组合模式