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

来源:互联网 发布:菜鸟网络p7薪酬 编辑:程序博客网 时间:2024/05/16 00:30
定义
将对象组合成树形结构以表示“部分-整体”的层次结构。组合(Composite)模式使得用户对单个对象和组合对象的使用具有一致性。
 
结构
 
 
理解
1.       Component是组合对象的基类,定义了类的公共方法;提供一个访问和管理子组件的方法。
管理子组件的方法:Add-添加子组件;Remove-移除子组件;GetChild-遍历获取组建对象的指针。
Operation是需要子组件具体定义的公共接口。
2.       Leaf是组合对象的叶子节点(树叶)。叶子节点没有子组件(也就没有管理子组件的方法),只有公共行为方法Operation
3.       Composite是具体的子组件类(树枝)。实现基类接口。它可以继续派生子组件或者叶子节点。
4.       Client通过Component基类来操作组合对象。
 
要点
1.       组合模式提供了一种解决对象之间递归组合的解决办法。组合对象包含两种派生类:包含子组件的树枝(Composite)和叶子组件的树叶(Leaf)。这样组合对象就可以继续组合对象,形成复杂的组合对象应用。
2.       最大化组合对象基类Component。客户是不知道具体对象调用的是Leaf还是Composite。为了达到这个目的,基类Component的方法就要最大化,并且提供默认实现,LeafComposite根据实际情况来重新实现。
 
应用
1.       多级菜单的实现可以使用组合模式。
2.       著名的开源测试框架XUnitJUnitCppUnit)系列,就是使用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