C++设计模式-组合模式

定义
将对象组合成树形结构以表示“部分- 整体”的层次结构。组合(Composite )模式使得用户对单个对象和组合对象的使用具有一致性。
 
结构
 
 
理解
1.       Component 是组合对象的基类,定义了类的公共方法;提供一个访问和管理子组件的方法。
管理子组件的方法:Add- 添加子组件;Remove- 移除子组件;GetChild- 遍历获取组建对象的指针。
Operation 是需要子组件具体定义的公共接口。
2.       Leaf 是组合对象的叶子节点(树叶)。叶子节点没有子组件(也就没有管理子组件的方法),只有公共行为方法Operation
3.       Composite 是具体的子组件类(树枝)。实现基类接口。它可以继续派生子组件或者叶子节点。
4.       Client 通过Component 基类来操作组合对象。
 
要点
1.       组合模式提供了一种解决对象之间递归组合的解决办法。组合对象包含两种派生类:包含子组件的树枝(Composite )和叶子组件的树叶(Leaf )。这样组合对象就可以继续组合对象,形成复杂的组合对象应用。
2.       最大化组合对象基类Component 。客户是不知道具体对象调用的是Leaf 还是Composite 。为了达到这个目的,基类Component 的方法就要最大化,并且提供默认实现,Leaf Composite 根据实际情况来重新实现。
 
应用
1.       多级菜单的实现可以使用组合模式。
2.       著名的开源测试框架XUnit JUnit CppUnit )系列,就是使用Composite 模式,更多可以参考: http://junit.sourceforge.net/doc/cookstour/cookstour.htm
源码中模拟XUnit ,使用Composite 实现测试框架。
 
源码
#include <iostream>
#include <set>
#include <string>
using namespace std;
 
// 组合对象基类 Component
class CTestComponent
{
public :
    CTestComponent() {};
    CTestComponent(const string &strName) : m_strName(strName){};
    virtual ~CTestComponent() {};
 
    // 测试工作方法。相当于模式的 Operation
    virtual void RunTest() {};
 
    // 增加一个测试组件
    virtual void Add(CTestComponent* p) {cout << "add" << endl;};
    // 移除一个测试组件
    virtual void Remove(CTestComponent* p) {};
 
    // 测试用例名称
    string m_strName;
};
 
// 组合对象子组件 Composite
class CTestComposite : public CTestComponent
{
public :
    CTestComposite() {};
    CTestComposite(const string &strName) : CTestComponent(strName)
    {};
    virtual ~CTestComposite() {};
 
    virtual void RunTest()
    {
        for (SetTestComponentItr itr = m_setComponent.begin(); itr != m_setComponent.end(); itr++)
        {
            cout << "run test name: " << (*itr)->m_strName << endl;
            (*itr)->RunTest();
        }
    };
 
    virtual void Add(CTestComponent* p) {
        cout << "add test name: " << p->m_strName << endl;
        m_setComponent.insert(p);
    };
 
    virtual void Remove(CTestComponent* p) {
        cout << "remove test name: " << p->m_strName << endl;
        m_setComponent.erase(p);
    };
 
protected :
    set<CTestComponent*> m_setComponent;
    typedef set<CTestComponent*> SetTestComponent;
    typedef set<CTestComponent*>::iterator SetTestComponentItr;
};
 
 
// 应用模式
/
#define TEST_RESULT(a, b) /
{   /
    if ((a) == (b)) {   /
        cout << "   test (" << a << ", " << b << ") reuslt: TRUE" << endl; /
    }   /
    else { /
        cout << "   test (" << a << ", " << b << ") reuslt: FALSE" << endl; /
        /
    }   /
}   /
 
class CTestCasePlus : public CTestComposite
{
public :
    CTestCasePlus(const string &strName) : CTestComposite(strName)
    {};
 
    int Plus(const int a, const int b) {
        return a + b;
    }
 
    void RunTest()
    {
        int i = Plus(1, 2);
        cout << "   test: "<< i << " == (1 + 2)" << endl;
        TEST_RESULT(i, 3);
    }
};
 
class CTestCaseSubtract : public CTestComposite
{
public :
    CTestCaseSubtract(const string &strName) : CTestComposite(strName)
    {};
 
    int Subtract(const int a, const int b) {
        //return a – b;
        return ba; //error
    }
 
    void RunTest()
    {
        int i = Subtract(1, 2);
        cout << "   test: "<< i << " == (1 – 2)" << endl;
        TEST_RESULT(i, -1);
    }
};
 
int main()
{
    CTestCasePlus testCase1("TestCasePlus");
    CTestCaseSubtract testCase2("TestCaseSubtract");
 
    //Client 调用
    CTestComposite composite;
    composite.Add(&testCase1);
    composite.Add(&testCase2);
    composite.RunTest();
    composite.Remove(&testCase1);
    composite.Remove(&testCase2);
 
    system("pause");
    return 0;
}
 
输出:
add test name: TestCasePlus
add test name: TestCaseSubtract
run test name: TestCaseSubtract
   test: 1 == (1 – 2)
   test (1, -1) reuslt: FALSE
run test name: TestCasePlus
   test: 3 == (1 + 2)
   test (3, 3) reuslt: TRUE
remove test name: TestCasePlus
remove test name: TestCaseSubtract
 
 

 

转载本站文章请注明,转载自:神秘果

本文链接: http://www.shenmiguo.com/archives/2009/303_design-patterns-composite.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值