適用場景
Composite模式適用於可以自包含的情況,比如說一個文件夾包含多個子文件夾,每個子文件夾又可以包含多個子文件夾。類似的問題還有:一個圓可以包含許多小圓,每一個小圓內部又可以包含多個圓。
模式介紹
Composite模式主要涉及到繼承和委託(Delegation)的結合,此處以圓爲例的UML圖如下所示:其中SingleCircle爲單一圓,Circle爲正常的圓裏面可以包含多個其他的圓,由於Circle的成員變量要能夠添加單個的圓或者很多圓,因此使用一個CircleBase作爲其基類,並有一個virtual add function, SingleCircle代表單個圓,因此不需要重寫add函數,Circle裏重寫add函數並以基類指針CircleBase*作爲指針(即委託),這樣即可以添加SingleCircle,又可以添加Circle。同樣把Circle換成File可以來描述文件包含多個文件的情況。
模式實現
以下代碼爲前面UML圖的實現,並測試了Composite模式
#include <vector>
#include <iostream>
class CircleBase
{
private:
int m_Value;
public:
CircleBase(int value)
:m_Value(value)
{}
virtual void add(CircleBase*){}
int radius()
{
return m_Value;
}
};
class SingleCircle : public CircleBase
{
public:
SingleCircle(int value):
CircleBase(value)
{
std::cout << "Create a single circle with radius: " << value << "." << std::endl;
}
};
class Circle: public CircleBase
{
private:
std::vector<CircleBase*> m_Circles;
public:
Circle(int value)
:CircleBase(value)
{
std::cout << "Create a circle can contain many circles with radius: " << value << "." << std::endl;
}
void add(CircleBase* circle)
{
std::cout << "Add a circle to circles with radius: " << circle->radius() << "." << std::endl;
m_Circles.push_back(circle);
}
};
int main()
{
Circle c1(1);
Circle c2(2);
SingleCircle sc(3);
c1.add(&c2);
c1.add(&sc);
}
運行結果:
D:\myproject\DesignPatterns\CompositePattern\bin>CompositePattern.exe
Create a circle can contain many circles with radius: 1.
Create a circle can contain many circles with radius: 2.
Create a single circle with radius: 3.
Add a circle to circles with radius: 2.
Add a circle to circles with radius: 3.
開發環境:Win10&VS2015
項目地址:
https://github.com/yazhouzheng/DesignPattens/tree/master/CompositePattern.