GeekBand-笔记-设计模式-02

建议下载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();**

}*

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,376评论 6 491
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,126评论 2 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 156,966评论 0 347
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,432评论 1 283
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,519评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,792评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,933评论 3 406
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,701评论 0 266
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,143评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,488评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,626评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,292评论 4 329
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,896评论 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,742评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,977评论 1 265
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,324评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,494评论 2 348

推荐阅读更多精彩内容