设计模式(8)——组合 Composite

本文介绍组合模式的基本概念,包括其意图、适用场景,并提供C++实现示例。通过组合模式,可以将对象组织成树状结构,实现对单个对象与组合对象一致的操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录:

设计模式学习笔记首页
设计模式(1)——抽象工厂 AbstractFactory
设计模式(2)——生成器 Builder
设计模式(3)——工厂方法 Factory Method
设计模式(4)——原型 Prototype
设计模式(5)——单例 Singleton
设计模式(6)——适配器 Adapter
设计模式(7)——桥接 Bridge
设计模式(8)——组合 Composite
设计模式(9)——装饰 Decorator
设计模式(10)——外观 Facade
设计模式(11)——享元 Flyweight
设计模式(12)——代理 Proxy
设计模式(13)——职责链 Chain Of Responsibility
设计模式(14)——命令 Command
设计模式(15)——解释器 Interpreter
设计模式(16)——迭代器 Iterator
设计模式(17)——中介者 Mediator
设计模式(18)——备忘录 Memento
设计模式(19)——观察者 Observer
设计模式(20)——状态 State
设计模式(21)——策略 Strategy
设计模式(22)——模板方法 Template Method
设计模式(23)——访问者 Visitor

八、Composite(组合模式,对象结构型模式)

1. 意图:

  将对象组合成树形结构以表示“部分-整体”的层次结构。Composite 使得用户对单个对象和组合对象的使用具有一致性

2. 适用:

  1. 想表示对象的部分-整体层次结构
  2. 希望用户忽略组合对象与单个对象的不同,用户将统一地使用组合结构中的所有对象

3. 类图:

image

4. 相关模式:

  通常部件-父部件连接用于 Responsibility of Chain 模式。
  Decorator 模式经常与 Composite 模式一起使用。当装饰和组合一起使用时,它们通常有一个公共的父类。因此装饰必须支持具有 Add、Remove 和 GetChild 操作的 Component 接口。

5. C++实现:

  1. 编写一个组件抽象基类(接口) Component,含有操作函数 OperationAddRemoveGetChild
  2. 编写一个叶子(部分)类 Leaf,一个组合(整体)类 Composite,都通过继承 Component 而具有一致性的操作 Operation
Composite.h
//Composite.h
#ifndef _COMPOSITE_H_
#define _COMPOSITE_H_

#include <vector>
using namespace::std;

/*
Component抽象基类,为组合中的对象声明接口,声明了类共有接口的缺省行为
如这里的Add,Remove,GetChild函数,声明一个接口函数可以访问Component的子组件
*/

class Component
{
public:
    virtual void Operation() = 0;
    virtual void Add(Component*);
    virtual void Remove(Component*);
    virtual Component* GetChild(int index);
    virtual ~Component();
protected:
    Component();
};

//Leaf是叶子结点,也就是不含有子组件的结点类,所以不用实现Add,Remove,GetChild等方法
class Leaf : public Component
{
public:
    //只实现Operation接口
    virtual void Operation();
    Leaf();
    ~Leaf();
};

//Composite含有子组件的类
class Composite : public Component
{
public:
    Composite();
    ~Composite();
    //实现所有接口
    void Operation();
    void Add(Component*);
    void Remove(Component*);
    Component* GetChild(_Uint32t index);
private:
    //这里采用vector来保存子组件
    vector<Component*> m_ComVec;
};

#endif
Composite.cpp
//Composite.cpp
#include "Composite.h"
#include <iostream>
#include <algorithm>

using namespace::std;

Component::Component(){}

Component::~Component(){}

void Component::Add(Component* com)
{
    cout << "add" << endl;
}

void Component::Remove(Component* com)
{
    //..
}

void Component::Operation()
{
    //..
    cout << "Component::Operation" << endl;
}

Component* Component::GetChild(int index)
{
    return NULL;
}

Leaf::Leaf(){}
Leaf::~Leaf(){}

void Leaf::Operation()
{
    cout << "Leaf::Operation" << endl;
}

Composite::Composite(){}
Composite::~Composite(){}

void Composite::Add(Component* com)
{
    this->m_ComVec.push_back(com);
}

void Composite::Remove(Component* com)
{
    vector<Component*>::iterator iter;
    iter = std::find(this->m_ComVec.begin(), m_ComVec.end(), com);
    while (m_ComVec.end() != iter)
    {
        m_ComVec.erase(iter);
        iter = std::find(m_ComVec.begin(), m_ComVec.end(), com);
    }
}

void Composite::Operation()
{
    cout << "Composite::Operation" << endl;
    vector<Component*>::iterator iter = this->m_ComVec.begin();
    for(; iter != this->m_ComVec.end(); iter++)
    {
        (*iter)->Operation();//递归
    }
}

Component* Composite::GetChild(_Uint32t index)
{
    if(index < 0 || index > this->m_ComVec.size())
    {
        return NULL;
    }
    return this->m_ComVec[index];
}
main.cpp
//main.cpp
#include "Composite.h"
#include <iostream>
using namespace::std;

int main()
{
    Leaf* pLeaf1 = new Leaf();
    Leaf* pLeaf2 = new Leaf();

    //叶子与组合对象都继承了相同的接口,所以语法上是对的,但
    //叶子Add,Remove,GetChild函数没有重新定义,都继承自基类,
    //没有实际意义。
    pLeaf1->Add(pLeaf2);
    pLeaf1->Remove(pLeaf2);

    //叶子结点实现了Opeeration()方法,
    pLeaf1->Operation();

    //组合对象实现了基类的所有接口,所以可以做各种操作(Add,Remove
    //GetChild,Operation)。
    Composite* pCom = new Composite();
    //组合对象添加叶子结点
    pCom->Add(pLeaf1);
    pCom->Add(pLeaf2);
    pCom->Operation();

    Composite* pRoot = new Composite();
    pRoot->Add(new Leaf());
    //组合对象添加组合对象
    pRoot->Add(pCom);
    pRoot->Operation();
    cin.get();

    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值