建议下载pdf附件。
l Factory Method****(工厂方法)****
**
意图:**
**
定义一个用于创建对象的接口,让子类决定实例化哪一个类。Factory Method 使一个类的实例化延迟到其子类。
适用性:**
**
当一个类不知道它所必须创建的对象的类的时候。
当一个类希望由它的子类来指定它所创建的对象的时候。
当类将创建对象的职责委托给多个帮助子类中的某一个,并且你希望将哪一个帮助子类是代理者这一信息局部化的时候。
代码实现:
**
#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****(抽象工厂)****
**
意图:**
**
提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。
适用性:**
**
一个系统要独立于它的产品的创建、组合和表示时。
一个系统要由多个产品系列中的一个来配置时。
当你要强调一系列相关的产品对象的设计以便进行联合使用时。
当你提供一个产品类库,而只想显示它们的接口而不是实现时。
代码实现:
**
#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****(原型)****
**
意图:**
**
用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。
适用性:**
**
当要实例化的类是在运行时刻指定时,例如,通过动态装载。
为了避免创建一个与产品类层次平行的工厂类层次时。
当一个类的实例只能有几个不同状态组合中的一种时。
建立相应数目的原型并克隆它们可能比每次用合适的状态手工实例化该类更方便一些。
代码实现:
**
#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(建造者)
意图:**
**
将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
适用性:**
**
当创建复杂对象的算法应该独立于该对象的组成部分以及它们的装配方式时。
当构造过程必须允许被构造的对象有不同的表示时。
代码实现:
**
#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****(外观)****
**
意图:**
**
为子系统中的一组接口提供一个一致的界面,Facade模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。
**
适用性:**
**
当你要为一个复杂子系统提供一个简单接口时。子系统往往因为不断演化而变得越来越复杂。大多数模式使用时都会产生更多更小的类。这使得子系统更具可重用性,也更容易对子系统进行定制,但这也给那些不需要定制子系统的用户带来一些使用上的困难。Facade 可以提供一个简单的缺省视图,这一视图对大多数用户来说已经足够,而那些需要更多的可定制性的用户可以越过facade层。
客户程序与抽象类的实现部分之间存在着很大的依赖性。引入facade 将这个子系统与客户以及其他的子系统分离,可以提高子系统的独立性和可移植性。
当你需要构建一个层次结构的子系统时,使用facade模式定义子系统中每层的入口点。如果子系统之间是相互依赖的,你可以让它们仅通过facade进行通讯,从而简化了它们之间的依赖关系。
代码实现:
**
#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(代理)
**意图:****
**
为其他对象提供一种代理以控制对这个对象的访问。
适用性:**
**
在需要用比较通用和复杂的对象指针代替简单的指针的时候,使用Proxy模式。下面是一些可以使用Proxy 模式常见情况:
远程代理(Remote Proxy )为一个对象在不同的地址空间提供局部代表。
虚代理(Virtual Proxy )根据需要创建开销很大的对象。
保护代理(Protection Proxy )控制对原始对象的访问。
智能指引(Smart Reference )取代了简单的指针,它在访问对象时执行一些附加操作。
代码实现:
**
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(适配器)
意图:**
**
将一个类的接口转换成客户希望的另外一个接口。Adapter 模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。
适用性:**
**
你想使用一个已经存在的类,而它的接口不符合你的需求。
你想创建一个可以复用的类,该类可以与其他不相关的类或不可预见的类(即那些接口可能不一定兼容的类)协同工作。
(仅适用于对象Adapter )你想使用一些已经存在的子类,但是不可能对每一个都进行子类化以匹配它们的接口。对象适配器可以适配它的父类接口。
**代码实现:
**
#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();**
}*