1.Composite
假如寫一個file system,可以知道一個文件系統可以包括有目錄和文件。
目錄裏面可以放文件。
由圖中可得,左邊的Primitive就是一個文件,右邊的Composite就是一個目錄。
目錄中需要一個容器來來存放文件,當然,目錄中也可以存放目錄,這個時候vector中存放的指針應該怎麼做?
那就讓文件和目錄同時繼承Component,讓vector來存放Component的指針。
並且目錄又可以委託Component*。
這樣Composite就可以存放文件也可以存放目錄。
大致的代碼:
class Component
{
int value;
public:
Component(int val){ value=val; }
virtual void add (Component*) {}
};
class Primitive : public Component
{
public:
Primitive(int val):Component(val){}
};
class Composite : public Component
{
vector<Component*> c;
public:
Composite(int val) : Component(val) {}
void add(Component* elem)
{
c.pubsh_back(elem);
}
};
爲什麼Component中的add不寫成純虛函數,因爲Primitive一個文件可不能再來add什麼,所以設置成一個空虛函數。
爲什麼vector中存放的是指針?因爲容器中存放的東西一定要大小一樣的,所以存放指針。
整個看起來就是23個設計模式中的一種Composite設計模式。
2.Prototype
註釋:(圖中帶有下劃線的是靜態類型,帶-號的爲private,帶#爲protected,帶+號,一般默認不加爲public)
Prototype原型設計模式,主要用於來寫未來的類,這樣的類我還不知道叫什麼,一般用於框架的構建。
用於,當未來我要寫一個LandSatImage的類,我讓它拷貝一份原型,讓最頂上的Image知道。
通俗來說,就是每一個子類都有一個自己,每一個子類都通過自己的構造函數把自己這個個體放進Image中。
並且每個子類都有一個clone,讓框架端知道自己的原型,並且通過原型來調用clone來製造子類的副本。
父類代碼:
#include <iosteam.h>
enum imageType
{
LSAT,SPOT
};
class Image
{
public :
virtual void draw() = 0;
static Image *findAndClone(imageType);
protected:
virtual imgeType returnType() = 0;
virtual Image *clone() = 0;
static void addPrototype(Image *image)
{
_prototypes[_nextSlot++] = image;
}
private:
static Image *_prototyles[10];
static int _nextSlot;
};
Image *Image::_prototype[];
int Image::_nextSlot;
靜態的聲明要在類外定義給內存。Image *Image::findAndClone(imageType type)
{
for(int i = 0; i<_nextSlot; i++)
if(_prototypes[i]->returnType() == type)
return _prototypes[i]->clone();
}
這裏利用枚舉,作爲示例,實際情況可能會使用類的名字。
找到原型之後調用clone做一個副本。
子類代碼:
class LandSatImage : public Image
{
public :
imageType returnType(){return LSAT;}
void draw(){cout<<"LandSatImage::draw"<<id<<endl;
Image *clone(){return new LandSatImage(1); }
protected:
LandSatImage(int dummy){_id=_count++; }
private:
static LandSatImage _landeSatImage;
LandSatImage(){ addProtetype(this); }
int _id;
static int _count;
};
LandSatImage LandSatImage::_landSatImage;
int LandSatImage::_count = 1;
最後看看子類圖中有-LanSatImage();#LandSatImage(int);爲什麼會有兩個構造函數分別再private與protecte。
我們先把靜態的自己放到框架端上了,並且實現findAndClone中的clone(),這個時候又要調用構造函數,
這次調用的構造函數不能調用-LandSatImage(),因爲如果再調用的話,又會往上加入一個原型。所以必須
要再寫一個構造函數,爲什麼不能寫在public中?因爲這個設計模式不是讓外界來讓他創建,而是讓原型來創建。
爲了區分開兩個構造函數,那就加一個參數int,但是這個int 根本用不到。