Design Pattern


《设计模式:可复用面向对象软件的基础》[美] Erich Gamma,[美] Richard Helm,[美] Ralph Johnson

创建型模式


ABSTRACT FACTORY(抽象工厂)

 

BUILDER(生成器)

 

FACTORY METHOD(工厂方法)

 

PROTOTYPE(原型)

 

SINGLETON(单件)

 

 

结构型模式


ADAPTER(适配器)

(1)意图:将一个类的接口转换成客户希望的另外一个接口。Adapter 模式使得原本由于接口不兼容
而不能一起工作的那些类可以一起工作。

(2)适用性:

你想使用一个已经存在的类,而它的接口不符合你的需求。

你想创建一个可以复用的类,该类可以与其他不相关的类或不可预见的类(即那些接口
可能不一定兼容的类)协同工作。

(仅适用于对象 Adapter )你想使用一些已经存在的子类,但是不可能对每一个都进行
子类化以匹配它们的接口。对象适配器可以适配它的父类接口。

(3)结构:

 

(4)效果:

类适配器:

  • 用一个具体的 Adapter 类对 Adaptee 和 Target 进行匹配。结果是当我们想要匹配一个类以
    及所有它的子类时,类 Adapter 将不能胜任工作。
  • 使得 Adapter 可以重定义 Adaptee 的部分行为,因为 Adapter 是 Adaptee 的一个子类。
  • 仅仅引入了一个对象,并不需要额外的指针以间接得到 Adaptee。

对象适配器:

  • 允许一个 Adapter 与多个 Adaptee —即 Adaptee 本身以及它的所有子类(如果有子类的话)
    —同时工作。Adapter 也可以一次给所有的 Adaptee 添加功能。
  • 使得重定义 Adaptee 的行为比较困难。这就需要生成 Adaptee 的子类并且使得 Adapter 引用
    这个子类而不是引用 Adaptee 本身。

(5)代码示例:

类适配器:

// sizeof(Target) = 4
class Target
{
public:
    virtual void Request() { cout << "Target: Request()" << endl; }
};
// sizeof(Adaptee) = 1
class Adaptee
{
public:
    void SpecificRequest() { cout << "Adaptee: SpecificRequest()" << endl; }
};
// sizeof(Adapter) = 4
class Adapter : public Target, private Adaptee
{
public:
    void Request() { SpecificRequest(); }
};

class Client
{
public:
    Client(Target *t) : target(t) {}
    Target *target;
};

Target *pTarget = new Adapter;
Client client(pTarget);
client.target->Request();
delete pTarget;

对象适配器:

class Target
{
public:
    virtual void Request() { cout << "Target: Request()" << endl; }
};

class Adaptee
{
public:
    void SpecificRequest() { cout << "Adaptee: SpecificRequest()" << endl; }
};
// sizeof(Adapter) = 8
class Adapter : public Target
{
public:
    Adapter(Adaptee *a) : adaptee(a) {}
    void Request() { adaptee->SpecificRequest(); }

private:
    Adaptee *adaptee;
};

class Client
{
public:
    Client(Target *t) : target(t) {}
    Target *target;
};

Adaptee *pAdaptee = new Adaptee;
Target *pTarget = new Adapter(pAdaptee);
Client client(pTarget);
client.target->Request();
delete pTarget;
delete pAdaptee;

 


BRIDGE(桥接)

(1)意图:将抽象部分与它的实现部分分离,使它们都可以独立地变化。

(2)适用性:

  • 你不希望在抽象和它的实现部分之间有一个固定的绑定关系。例如这种情况可能是因为,
    在程序运行时刻实现部分应可以被选择或者切换。
  • 类的抽象以及它的实现都应该可以通过生成子类的方法加以扩充。这时 Bridge 模式使你
    可以对不同的抽象接口和实现部分进行组合,并分别对它们进行扩充。
  • 对一个抽象的实现部分的修改应对客户不产生影响,即客户的代码不必重新编译。
  • (C++)你想对客户完全隐藏抽象的实现部分。在 C++ 中,类的表示在类接口中是可见
    的。
  • 正如在意图一节的第一个类图中所示的那样,有许多类要生成。这样一种类层次结构说
    明你必须将一个对象分解成两个部分。Rumbaugh 称这种类层次结构为“嵌套的普化”
    (nested generalizations)。
  • 你想在多个对象间共享实现(可能使用引用计数),但同时要求客户并不知道这一点。

(3)结构:

 

(4)效果:

  • 分离接口及其实现部分    一个实现未必不变地绑定在一个接口上。抽象类的实现可以在运行时刻进行配置,一个对象甚至可以在运行时刻改变它的实现。将 Abstraction 与 Implementor 分离有助于降低对实现部分编译时刻的依赖性,当改变一个实现类时,并不需要重新编译 Abstraction 类和它的客户程序。为了保证一个类库的不同版本之间的二进制兼容性,一定要有这个性质。另外,接口与实现分离有助于分层,从而产生更好的结构化系统,系统的高层部分仅需知道 Abstraction 和 Implementor 即可。
  • 提高可扩充性    你可以独立地对 Abstraction 和 Implementor 层次结构进行扩充。
  • 实现细节对客户透明    你可以对客户隐藏实现细节,例如共享 Implementor 对象以及相应的引用计数机制(如果有的话)

(5)代码示例:

class Implementor
{
public:
    virtual void OperationImp() { cout << "Implementor: OperationImp()" << endl; }
};

class ConcreteImplementorA : public Implementor
{
public:
    void OperationImp() { cout << "ConcreteImplementorA: OperationImp()" << endl; }
};

class ConcreteImplementorB : public Implementor
{
public:
    void OperationImp() { cout << "ConcreteImplementorB: OperationImp()" << endl; }
};

class Abstraction
{
public:
    Abstraction(Implementor *i) : imp(i) {}
    virtual void Operation() { imp->OperationImp(); }
    void setImplementor(Implementor *i) { imp = i; }

private:
    Implementor *imp;
};

class RefinedAbstraction : public Abstraction
{
public:
    RefinedAbstraction(Implementor *i) : Abstraction(i) {}
    void Operation()
    {
        Abstraction::Operation();
        cout << "RefinedAbstraction: Operation()" << endl;
    }
};

class Client
{
public:
    Client(Abstraction *a) : abstraction(a) {}
    Abstraction *abstraction;
};

Implementor *pImplementorA = new ConcreteImplementorA;
Implementor *pImplementorB = new ConcreteImplementorB;
Abstraction *pAbstraction = new RefinedAbstraction(pImplementorA);
Client client(pAbstraction);
client.abstraction->Operation();
pAbstraction->setImplementor(pImplementorB);
client.abstraction->Operation();
delete pAbstraction;
delete pImplementorA;
delete pImplementorB;

 

COMPOSITE(组合)

 

DECORATOR(装饰)

 

FACADE(外观)

 

FLYWEIGHT(享元)

 

PROXY(代理)

 

 

行为模式


CHAIN OF RESPONSIBILITY(职责链)

 

COMMAND(命令)

 

INTERPRETER(解释器)

 

ITERATOR(迭代器)

 

MEDIATOR(中介者)

 

MEMENTO(备忘录)

 

OBSERVER(观察者)

 

STATE(状态)

 

STRATEGY(策略)

 

TEMPLATE METHOD(模板方法)

 

VISITOR(访问者)