建議下載pdf附件。
l Factory Method****(工廠方法)****
**
意圖:**
**
定義一個(gè)用于創(chuàng)建對(duì)象的接口伏伐,讓子類決定實(shí)例化哪一個(gè)類祈餐。Factory Method 使一個(gè)類的實(shí)例化延遲到其子類鹃操。
適用性:**
**
當(dāng)一個(gè)類不知道它所必須創(chuàng)建的對(duì)象的類的時(shí)候仓坞。
當(dāng)一個(gè)類希望由它的子類來指定它所創(chuàng)建的對(duì)象的時(shí)候颜说。
當(dāng)類將創(chuàng)建對(duì)象的職責(zé)委托給多個(gè)幫助子類中的某一個(gè)购岗,并且你希望將哪一個(gè)幫助子類是代理者這一信息局部化的時(shí)候。
代碼實(shí)現(xiàn):
**
#include
<iostream.h>*
/
Abstract base class declared by framework /*
class
Document*
{*
public:**
Document(char *fn)**
{**
strcpy(name,
fn);**
}**
virtual void Open() = 0;**
virtual void Close() = 0;**
char *GetName()**
{**
return name;**
}**
private:**
char name[20];**
};*
/
Concrete derived class defined by client /*
class
MyDocument: public Document*
{*
public:**
MyDocument(char *fn):
Document(fn){}**
void Open()**
{**
cout <<
" MyDocument: Open()" << endl;**
}**
void Close()**
{**
cout <<
" MyDocument: Close()" << endl;**
}**
};*
/
Framework declaration /*
class
Application*
{*
public:**
Application(): _index(0)**
{**
cout <<
"Application: ctor" << endl;**
}**
/* The client will call this
"entry point" of the framework /*
NewDocument(char *name)**
{**
cout <<
"Application: NewDocument()" << endl;**
/* Framework
calls the "hole" reserved for client customization /*
_docs[_index]
= CreateDocument(name);**
_docs[_index++]->Open();**
}**
void OpenDocument(){}**
void ReportDocs();**
/* Framework declares a
"hole" for the client to customize /*
virtual Document
CreateDocument(char) = 0;**
private:**
int _index;**
/* Framework uses Document's
base class /*
Document *_docs[10];**
};*
void
Application::ReportDocs()*
{*
cout << "Application:
ReportDocs()" << endl;**for (int i = 0; i < _index;i++)**
cout << "
" << _docs[i]->GetName() << endl;**
}*
/
Customization of framework defined by client /*
class
MyApplication: public Application*
{*
public:**
MyApplication()**
{**
cout <<
"MyApplication: ctor" << endl;**
}**
/* Client definesFramework's "hole" */**
Document *CreateDocument(char
fn)*
{**
cout <<
" MyApplication: CreateDocument()" << endl;**
return new
MyDocument(fn);**
}**
};*
int
main()*
{*
/* Client's customization of the
Framework /*MyApplication myApp;**
myApp.NewDocument("foo");**
myApp.NewDocument("bar");**
myApp.ReportDocs();**
}
l Abstract Factory****(抽象工廠)****
**
意圖:**
**
提供一個(gè)創(chuàng)建一系列相關(guān)或相互依賴對(duì)象的接口门粪,而無需指定它們具體的類喊积。
適用性:**
**
一個(gè)系統(tǒng)要獨(dú)立于它的產(chǎn)品的創(chuàng)建、組合和表示時(shí)玄妈。
一個(gè)系統(tǒng)要由多個(gè)產(chǎn)品系列中的一個(gè)來配置時(shí)乾吻。
當(dāng)你要強(qiáng)調(diào)一系列相關(guān)的產(chǎn)品對(duì)象的設(shè)計(jì)以便進(jìn)行聯(lián)合使用時(shí)髓梅。
當(dāng)你提供一個(gè)產(chǎn)品類庫,而只想顯示它們的接口而不是實(shí)現(xiàn)時(shí)绎签。
代碼實(shí)現(xiàn):
**
#include
<iostream.h>*
class
Shape {*
public:**
Shape() {**
id_ = total_++;**
}**
virtual void draw() = 0;**
protected:**
int id_;**
static int total_;**
};*
int
Shape::total_ = 0;*
class
Circle : public Shape {*
public:**
void draw() {**
cout <<
"circle " << id_ << ":
draw" << endl;**
}**
};*
class
Square : public Shape {*
public:**
void draw() {**
cout <<
"square " << id_ << ": draw" << endl;**
}**
};*
class
Ellipse : public Shape {*
public:**
void draw() {**
cout <<
"ellipse " << id_ << ": draw" << endl;**
}**
};*
class
Rectangle : public Shape {*
public:**
void draw() {**
cout <<
"rectangle " << id_ << ": draw" << endl;**
}**
};*
class
Factory {*
public:**
virtual Shape*
createCurvedInstance() = 0;**
virtual Shape*
createStraightInstance() = 0;**
};*
class
SimpleShapeFactory : public Factory {*
public:**
Shape* createCurvedInstance() {**
return new Circle;**
}**
Shape* createStraightInstance()
{**
return new Square;**
}**
};*
class
RobustShapeFactory : public Factory {*
public:**
Shape* createCurvedInstance() {**
return new Ellipse;**
}**
Shape* createStraightInstance()
{**
return new Rectangle;**
}**
};*
int
main() {*
#ifdef
SIMPLE*
Factory* factory = new
SimpleShapeFactory;**
#elif
ROBUST*
Factory* factory = new
RobustShapeFactory;**
#endif*
Shape* shapes[3];**
shapes[0] =
factory->createCurvedInstance(); // shapes[0] = new Ellipse;**shapes[1] =
factory->createStraightInstance(); // shapes[1] = new Rectangle;**shapes[2] =
factory->createCurvedInstance(); // shapes[2] = new Ellipse;**for (int i=0; i < 3; i++) {**
shapes[i]->draw();**
}**
}*
l Prototype****(原型)****
**
意圖:**
**
用原型實(shí)例指定創(chuàng)建對(duì)象的種類枯饿,并且通過拷貝這些原型創(chuàng)建新的對(duì)象。
適用性:**
**
當(dāng)要實(shí)例化的類是在運(yùn)行時(shí)刻指定時(shí)诡必,例如鸭你,通過動(dòng)態(tài)裝載。
為了避免創(chuàng)建一個(gè)與產(chǎn)品類層次平行的工廠類層次時(shí)擒权。
當(dāng)一個(gè)類的實(shí)例只能有幾個(gè)不同狀態(tài)組合中的一種時(shí)袱巨。
建立相應(yīng)數(shù)目的原型并克隆它們可能比每次用合適的狀態(tài)手工實(shí)例化該類更方便一些。
代碼實(shí)現(xiàn):
**
#include
<iostream.h>*
enum
imageType*
{*
LSAT, SPOT**
};*
class
Image*
{*
public:**
virtual void draw() = 0;**
static Image
findAndClone(imageType);*
protected:**
virtual imageType returnType()
= 0;**
virtual Image *clone() = 0;**
// As each subclass of Image is
declared, it registers its prototype**
static void addPrototype(Image
image)*
{**
_prototypes[_nextSlot++]
= image;**
}**
private:**
// addPrototype() saves each
registered prototype here**
static Image *_prototypes[10];**
static int _nextSlot;**
};*
Image
Image::_prototypes[];
int
Image::_nextSlot;*
//
Client calls this public static member function when it needs an instance*
//
of an Image subclass*
Image
Image::findAndClone(imageType type)
{*
for (int i = 0; i < _nextSlot; i++)**
if
(_prototypes[i]->returnType() == type)**
return _prototypes[i]->clone();**
}*
class
LandSatImage: public Image*
{*
public:**
imageType returnType()**
{**
return LSAT;**
}**
void draw()**
{**
cout <<
"LandSatImage::draw " << _id << endl;**
}**
// When clone() is called, call
the one-argument ctor with a dummy arg**
Image *clone()**
{**
return new
LandSatImage(1);**
}**
protected:**
// This is only called from
clone()**
LandSatImage(int dummy)**
{**
_id =
_count++;**
}**
private:**
// Mechanism for initializing
an Image subclass - this causes the**
// defaultctor to be called, which registers the subclass's prototype**
static LandSatImage
_landSatImage;**
// This is only called when the
private static data member is initiated**
LandSatImage()**
{**
addPrototype(this);**
}**
// Nominal "state"
per instance mechanism**
int _id;**
static int _count;**
};*
//
Register the subclass's prototype*
LandSatImage
LandSatImage::_landSatImage;*
//
Initialize the "state" per instance mechanism*
int
LandSatImage::_count = 1;*
class
SpotImage: public Image*
{*
public:**
imageTypereturnType()**
{**
return SPOT;**
}**
void draw()**
{**
cout <<
"SpotImage::draw " << _id << endl;**
}**
Image *clone()**
{**
return new
SpotImage(1);**
}**
protected:**
SpotImage(int dummy)**
{**
_id =
_count++;**
}**
private:**
SpotImage()**
{**
addPrototype(this);**
}**
static SpotImage _spotImage;**
int _id;**
static int _count;**
};*
SpotImage
SpotImage::_spotImage;*
int
SpotImage::_count = 1;*
//
Simulated stream of creation requests*
const
int NUM_IMAGES = 8;*
*imageType
input[NUM_IMAGES] = **
{*
LSAT, LSAT,
LSAT, SPOT, LSAT, SPOT, SPOT, LSAT**
};*
int
main()*
{*
Image images[NUM_IMAGES];*
// Given an image type, find the right
prototype, and return a clone**for (int i = 0; i < NUM_IMAGES; i++)**
images[i] =
Image::findAndClone(input[i]);**
// Demonstrate
that correct image objects have been cloned**for (i = 0; i < NUM_IMAGES; i++)**
images[i]->draw();**
// Free the dynamic memory**
for (i = 0; i < NUM_IMAGES; i++)**
delete images[i];**
}*
l Builder(建造者)
意圖:**
**
將一個(gè)復(fù)雜對(duì)象的構(gòu)建與它的表示分離碳抄,使得同樣的構(gòu)建過程可以創(chuàng)建不同的表示愉老。
適用性:**
**
當(dāng)創(chuàng)建復(fù)雜對(duì)象的算法應(yīng)該獨(dú)立于該對(duì)象的組成部分以及它們的裝配方式時(shí)。
當(dāng)構(gòu)造過程必須允許被構(gòu)造的對(duì)象有不同的表示時(shí)剖效。
代碼實(shí)現(xiàn):
**
#include
<iostream.h>*
#include
<stdio.h>*
#include
<string.h>*
enum
PersistenceType*
{*
File, Queue, Pathway**
};*
struct
PersistenceAttribute*
{*
PersistenceType type;**
char value[30];**
};*
class
DistrWorkPackage*
{*
public:**
DistrWorkPackage(char *type)**
{**
sprintf(_desc,
"Distributed Work Package for: %s", type);**
}**
void setFile(char *f, char *v)**
{**
sprintf(_temp,
"\n File(%s): %s", f, v);**
strcat(_desc,
_temp);**
}**
void setQueue(char
q, char v)
{**
sprintf(_temp,
"\n Queue(%s): %s", q, v);**
strcat(_desc,
_temp);**
}**
void setPathway(char *p, char
v)*
{**
sprintf(_temp,
"\n Pathway(%s): %s", p, v);**
strcat(_desc,
_temp);**
}**
const char *getState()**
{**
return _desc;**
}**
private:**
char _desc[200], _temp[80];**
};*
class
Builder*
{*
public:**
virtual void
configureFile(char) = 0;*
virtual void
configureQueue(char) = 0;*
virtual void
configurePathway(char) = 0;*
DistrWorkPackage *getResult()**
{**
return _result;**
}**
protected:**
DistrWorkPackage *_result;**
};*
class
UnixBuilder: public Builder*
{*
public:**
UnixBuilder()**
{**
_result = new
DistrWorkPackage("Unix");**
}**
void configureFile(char *name)**
{**
_result->setFile("flatFile",
name);**
}**
void configureQueue(char
queue)*
{**
_result->setQueue("FIFO",
queue);**
}**
void configurePathway(char
type)*
{**
_result->setPathway("thread",
type);**
}**
};*
class
VmsBuilder: public Builder*
{*
public:**
VmsBuilder()**
{**
_result = new
DistrWorkPackage("Vms");**
}**
void configureFile(char *name)**
{**
_result->setFile("ISAM",
name);**
}**
void configureQueue(char
queue)*
{**
_result->setQueue("priority",
queue);**
}**
void configurePathway(char
type)*
{**
_result->setPathway("LWP", type);**
}**
};*
class
Reader*
{*
public:**
void setBuilder(Builder *b)**
{**
_builder = b;**
}**
void
construct(PersistenceAttribute[], int);**
private:**
Builder *_builder;**
};*
void
Reader::construct(PersistenceAttribute list[], int num)*
{*
for (int i =
0; i < num; i++)**if (list[i].type == File)**
_builder->configureFile(list[i].value);**
else if (list[i].type == Queue)**
_builder->configureQueue(list[i].value);**
else if (list[i].type ==
Pathway)**
_builder->configurePathway(list[i].value);**
}*
const int NUM_ENTRIES = 6;*
*PersistenceAttribute
input[NUM_ENTRIES] = **
{*
{**
File, "state.dat"**
}**
, **
{**
File, "config.sys"**
}**
, **
{**
Queue, "compute"**
}**
, **
{**
Queue, "log"**
}**
, **
{**
Pathway,
"authentication"**
}**
, **
{**
Pathway, "error
processing"**
}**
};*
int
main()*
{*
UnixBuilder unixBuilder;**
VmsBuilder vmsBuilder;**
Reader reader;**
reader.setBuilder(&unixBuilder);**
reader.construct(input, NUM_ENTRIES);**
cout <<
unixBuilder.getResult()->getState() << endl;**reader.setBuilder(&vmsBuilder);**
reader.construct(input, NUM_ENTRIES);**
cout <<
vmsBuilder.getResult()->getState() << endl;**
}*
l Facade****(外觀)****
**
意圖:**
**
為子系統(tǒng)中的一組接口提供一個(gè)一致的界面嫉入,F(xiàn)acade模式定義了一個(gè)高層接口,這個(gè)接口使得這一子系統(tǒng)更加容易使用璧尸。
**
適用性:**
**
當(dāng)你要為一個(gè)復(fù)雜子系統(tǒng)提供一個(gè)簡(jiǎn)單接口時(shí)咒林。子系統(tǒng)往往因?yàn)椴粩嘌莼兊迷絹碓綇?fù)雜。大多數(shù)模式使用時(shí)都會(huì)產(chǎn)生更多更小的類爷光。這使得子系統(tǒng)更具可重用性垫竞,也更容易對(duì)子系統(tǒng)進(jìn)行定制,但這也給那些不需要定制子系統(tǒng)的用戶帶來一些使用上的困難蛀序。Facade 可以提供一個(gè)簡(jiǎn)單的缺省視圖欢瞪,這一視圖對(duì)大多數(shù)用戶來說已經(jīng)足夠,而那些需要更多的可定制性的用戶可以越過facade層徐裸。
客戶程序與抽象類的實(shí)現(xiàn)部分之間存在著很大的依賴性遣鼓。引入facade 將這個(gè)子系統(tǒng)與客戶以及其他的子系統(tǒng)分離,可以提高子系統(tǒng)的獨(dú)立性和可移植性重贺。
當(dāng)你需要構(gòu)建一個(gè)層次結(jié)構(gòu)的子系統(tǒng)時(shí)骑祟,使用facade模式定義子系統(tǒng)中每層的入口點(diǎn)。如果子系統(tǒng)之間是相互依賴的气笙,你可以讓它們僅通過facade進(jìn)行通訊次企,從而簡(jiǎn)化了它們之間的依賴關(guān)系。
代碼實(shí)現(xiàn):
**
#include
<iostream.h>*
class
MisDepartment*
{*
public:**
void submitNetworkRequest()**
{**
_state = 0;**
}**
bool checkOnStatus()**
{**
_state++;**
if (_state ==
Complete)**
return
1;**
return 0;**
}**
private:**
enum States**
{**
Received,
DenyAllKnowledge, ReferClientToFacilities,**
FacilitiesHasNotSentPaperwork,
ElectricianIsNotDone,**
ElectricianDidItWrong,
DispatchTechnician, SignedOff, DoesNotWork,**
FixElectriciansWiring,
Complete**
};**
int _state;**
};*
class
ElectricianUnion*
{*
public:**
void submitNetworkRequest()**
{**
_state = 0;**
}**
bool checkOnStatus()**
{**
_state++;**
if (_state ==
Complete)**
return
1;**
return 0;**
}**
private:**
enum States**
{**
Received,
RejectTheForm, SizeTheJob, SmokeAndJokeBreak,**
WaitForAuthorization,
DoTheWrongJob, BlameTheEngineer, WaitToPunchOut,**
DoHalfAJob,
ComplainToEngineer, GetClarification, CompleteTheJob,**
TurnInThePaperwork,
Complete**
};**
int _state;**
};*
class
FacilitiesDepartment*
{*
public:**
void submitNetworkRequest()**
{**
_state = 0;**
}**
bool checkOnStatus()**
{**
_state++;**
if (_state ==
Complete)**
return
1;**
return 0;**
}**
private:**
enum States**
{**
Received,
AssignToEngineer, EngineerResearches, RequestIsNotPossible,**
EngineerLeavesCompany,
AssignToNewEngineer, NewEngineerResearches,**
ReassignEngineer,
EngineerReturns, EngineerResearchesAgain,**
EngineerFillsOutPaperWork,
Complete**
};**
int _state;**
};*
class
FacilitiesFacade*
{*
public:**
FacilitiesFacade()**
{**
_count = 0;**
}**
void submitNetworkRequest()**
{**
_state = 0;**
}**
bool checkOnStatus()**
{**
_count++;**
/* Job
request has just been received /*
if (_state ==
Received)**
{**
_state++;**
/* Forward the job request to the
engineer /*
_engineer.submitNetworkRequest();**
cout << "submitted to Facilities - "
<< _count << **
" phone calls so far" << endl;**
}**
else if
(_state == SubmitToEngineer)**
{**
/* If engineer is complete, forward
to electrician /*
if (_engineer.checkOnStatus())**
{**
_state++;**
_electrician.submitNetworkRequest();**
cout << "submitted to Electrician - "
<< _count << **
" phone calls so far" << endl;**
}**
}**
else if (_state == SubmitToElectrician)**
{**
/* If electrician is complete, forward to technician */**
if (_electrician.checkOnStatus())**
{**
_state++;**
_technician.submitNetworkRequest();**
cout << "submitted to MIS - " <<_count << **
" phone calls so far" << endl;**
}**
}**
else if
(_state == SubmitToTechnician)**
{**
/* If technician is complete, job is done */**
if (_technician.checkOnStatus())**
return 1;**
}**
/* The job is
not entirely complete /*
return 0;**
}**
int getNumberOfCalls()**
{**
return
_count;**
}**
private:**
enum States**
{**
Received,
SubmitToEngineer, SubmitToElectrician, SubmitToTechnician**
};**
int _state;**
int _count;**
FacilitiesDepartment _engineer;**
ElectricianUnion _electrician;**
MisDepartment _technician;**
};*
int
main()*
{*
FacilitiesFacade facilities;**
facilities.submitNetworkRequest();**
/* Keep checking until job is complete
/*while (!facilities.checkOnStatus())**
;**
cout << "job completed after only " << facilities.getNumberOfCalls()
<< **" phone calls"
<< endl;**
}*
l Proxy(代理)
**意圖:****
**
為其他對(duì)象提供一種代理以控制對(duì)這個(gè)對(duì)象的訪問健民。
適用性:**
**
在需要用比較通用和復(fù)雜的對(duì)象指針代替簡(jiǎn)單的指針的時(shí)候抒巢,使用Proxy模式。下面是一些可以使用Proxy 模式常見情況:
遠(yuǎn)程代理(Remote Proxy )為一個(gè)對(duì)象在不同的地址空間提供局部代表秉犹。
虛代理(Virtual Proxy )根據(jù)需要?jiǎng)?chuàng)建開銷很大的對(duì)象蛉谜。
保護(hù)代理(Protection Proxy )控制對(duì)原始對(duì)象的訪問。
智能指引(Smart Reference )取代了簡(jiǎn)單的指針崇堵,它在訪問對(duì)象時(shí)執(zhí)行一些附加操作型诚。
代碼實(shí)現(xiàn):
**
class
Subject*
{*
public:**
virtual void execute() = 0;**
};*
class
RealSubject: public Subject*
{*
string str;**
public:**
RealSubject(string s)**
{**
str = s;**
}**
/*virtual*/void execute()**
{**
cout <<
str << '\n';**
}**
};*
class
ProxySubject: public Subject*
{*
string first, second, third;**
RealSubject *ptr;**
public:**
ProxySubject(string s)**
{**
int num =
s.find_first_of(' ');**
first =
s.substr(0, num);**
s = s.substr(num + 1);**
num =
s.find_first_of(' ');**
second =
s.substr(0, num);**
s =
s.substr(num + 1);**
num =
s.find_first_of(' ');**
third =
s.substr(0, num);**
s =
s.substr(num + 1);**
ptr = new
RealSubject(s);**
}**
~ProxySubject()**
{**
delete ptr;**
}**
RealSubject *operator->()**
{**
cout <<
first << ' ' << second << ' ';**
return ptr;**
}**
/*virtual*/void execute()**
{**
cout <<
first << ' ' << third << ' ';**
ptr->execute();**
}**
};*
int
main()*
{*
ProxySubject obj(string("the quick brown fox jumped over the dog"));**
obj->execute();**
obj.execute();**
}*
l Adapter
Class/Object(適配器)
意圖:**
**
將一個(gè)類的接口轉(zhuǎn)換成客戶希望的另外一個(gè)接口。Adapter 模式使得原本由于接口不兼容而不能一起工作的那些類可以一起工作鸳劳。
適用性:**
**
你想使用一個(gè)已經(jīng)存在的類狰贯,而它的接口不符合你的需求。
你想創(chuàng)建一個(gè)可以復(fù)用的類赏廓,該類可以與其他不相關(guān)的類或不可預(yù)見的類(即那些接口可能不一定兼容的類)協(xié)同工作涵紊。
(僅適用于對(duì)象Adapter )你想使用一些已經(jīng)存在的子類,但是不可能對(duì)每一個(gè)都進(jìn)行子類化以匹配它們的接口幔摸。對(duì)象適配器可以適配它的父類接口摸柄。
**代碼實(shí)現(xiàn):
**
#include
<iostream.h>*
typedef
int Coordinate;*
typedef
int Dimension;*
//
Desired interface*
class
Rectangle*
{*
public:**
virtual
void draw() = 0;**
};*
//
Legacy component*
class
LegacyRectangle*
{*
public:**
LegacyRectangle(Coordinate x1,
Coordinate y1, Coordinate x2, Coordinate y2)**
{**
x1_ = x1;**
y1_ = y1;**
x2_ = x2;**
y2_ = y2;**
cout <<
"LegacyRectangle: create. ("
<< x1_ << "," << y1_ << ") => ("**
<<
x2_ << "," << y2_ << ")" << endl;**
}**
void oldDraw()**
{**
cout <<
"LegacyRectangle: oldDraw. (" << x1_ <<
"," << y1_ << **
")
=> (" << x2_ << "," << y2_ <<
")" << endl;**
}**
private:**
Coordinate x1_;**
Coordinate y1_;**
Coordinate x2_;**
Coordinate y2_;**
};*
//
Adapter wrapper*
class
RectangleAdapter: public Rectangle, private LegacyRectangle*
{*
public:**
RectangleAdapter(Coordinate x,
Coordinate y, Dimension w, Dimension h):**
LegacyRectangle(x, y,
x + w, y + h)**
{**
cout <<
"RectangleAdapter: create. (" << x << ","
<< y << **
"),
width = " << w << ", height = " << h <<
endl;**
}**
virtual void draw()**
{**
cout <<
"RectangleAdapter: draw." << endl;**
oldDraw();**
}**
};*
int
main()*
{*
Rectangle r = new RectangleAdapter(120,
200, 60, 40);*r->draw();**
}*