设计模式二,Proxy,State,Adapter,Template Method

Proxy,可以理解为本身不提供实现方式,通过接口调用具体的实现。

//: C10:ProxyDemo.cpp
// Simple demonstration of the Proxy pattern.
#include <iostream>
using namespace std;
 
class ProxyBase {
public:
  virtual void f() = 0;
  virtual void g() = 0;
  virtual void h() = 0;
  virtual ~ProxyBase() {}
};
 
class Implementation : public ProxyBase {
public:
  void f() { cout << "Implementation.f()" << endl; }
  void g() { cout << "Implementation.g()" << endl; }
  void h() { cout << "Implementation.h()" << endl; }
};
 
class Proxy : public ProxyBase {
  ProxyBase* implementation;
public:
  Proxy() { implementation = new Implementation(); }
  ~Proxy() { delete implementation; }
  // Forward calls to the implementation:
  void f() { implementation->f(); }
  void g() { implementation->g(); }
  void h() { implementation->h(); }
};
 
int main()  {
  Proxy p;
  p.f();
  p.g();
  p.h();
} ///:~
<style type="text/css">.csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } </style>

state:改变对象的行为

状态模式产生一个可以改变其类的对象,当发现在大多数或者所有函数中都存在有条件的代码时,这种模式很有用。和代理模式一样,状态模式通过一个前端对象来使用后端实现对象履行其职责。然而,在前端对象生存期期间,状态模式从一个实现对象到另一个实现对象进行切换,以实现对于相同的函数调用产生不同的行为。

需要使用state模式的情境:

//: C10:KissingPrincess.cpp
#include <iostream>
using namespace std;
 
class Creature {
  bool isFrog;
public:
  Creature() : isFrog(true) {}
  void greet() {
    if(isFrog)
      cout << "Ribbet!" << endl;
    else
      cout << "Darling!" << endl;
  }
  void kiss() { isFrog = false; }
};
 
int main() {
  Creature creature;
  creature.greet();
  creature.kiss();
  creature.greet();
} ///:~
然而,greet()等任何其他所有函数在执行操作前都必须测试变量isFrog,这样就使代码变
得笨拙至极,特别是在系统中加入额外的状态时情况会更加严重。通过将操作委派给状态对
象,这种情况就可以改变,代码从而得到了简化。
//: C10:KissingPrincess2.cpp
// The State pattern.
#include <iostream>
#include <string>
using namespace std;
 
class Creature {
  class State {
  public:
    virtual string response() = 0;
  };
  class Frog : public State {
  public:
    string response() { return "Ribbet!"; }
  };
  class Prince : public State {
  public:
    string response() { return "Darling!"; }
  };
  State* state;
public:
  Creature() : state(new Frog()) {}
  void greet() {
    cout << state->response() << endl;
  }
  void kiss() {
    delete state;
    state = new Prince();
  }
};
 
int main() {
  Creature creature;
  creature.greet();
  creature.kiss();
  creature.greet();
} ///:~
<style type="text/css">.csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } </style>
 
<style type="text/css">.csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } </style> 在这里,将实现类设计为嵌套或者私有并不是必需的,但是如果能做到的话,就会创建出更加清晰的代码。

注意,对状态类的改变将会自动地在所有的代码中进行传播,而不需要编辑这些类来完成改变。

Adapter:适配器模式接受一种类型并且提供一个对其他类型的接口。当给定一个库或者具有某一接口的一段代码,同时还给定另外一个库或者与前面那段代码的基本思想相同的一段代码而只是表达方式不一致时,适配器模式将十分有用。通过调整彼此的表达方式以适配彼此,将会迅速产生解决方法。

以下代码比较复杂,一时还未参透,记下来再说:

 
 
 
 
class FibonacciGenerator {
    int n;
    int val[2];
public:
    FibonacciGenerator() : n(0) { val[0] = val[1] = 0; }
    int operator()() {
        int result = n > 2 ? val[0] + val[1] : n > 0 ? 1 : 0;
        ++n;
        val[0] = val[1];
        val[1] = result;
        return result;
    }
    int count() { return n; }
};
 
 
//: C10:FibonacciAdapter.cpp
// Adapting an interface to something you already have.
#include <iostream>
#include <numeric>
//#include "FibonacciGenerator.h"
#include "../PrintSequence.h"
using namespace std;
 
 
class FibonacciAdapter { // Produce an iterator
    FibonacciGenerator f;
    int length;
public:
    FibonacciAdapter(int size) : length(size) {}
    class iterator;
    friend class iterator;
    
    class iterator : public std::iterator<
        std::input_iterator_tag, FibonacciAdapter, ptrdiff_t> {
            FibonacciAdapter& ap;
    public:
        typedef int value_type;
        iterator(FibonacciAdapter& a) : ap(a) {}
        bool operator==(const iterator&) const {
            return ap.f.count() == ap.length;
        }
        bool operator!=(const iterator& x) const {
            return !(*this == x);
        }
        int operator*() const { return ap.f(); }
        iterator& operator++() { return *this; }
        iterator operator++(int) { return *this; }
    };
 
 
    iterator begin() { return iterator(*this); }
    iterator end() { return iterator(*this); }
};
 
 
int main() {
    const int SZ = 20;
    FibonacciAdapter a1(SZ);
    cout << "accumulate: "
        << accumulate(a1.begin(), a1.end(), 0) << endl;
    FibonacciAdapter a2(SZ), a3(SZ);
    cout << "inner product: "
        << inner_product(a2.begin(), a2.end(), a3.begin(), 0)
        << endl;
    FibonacciAdapter a4(SZ);
    int r1[SZ] = {0};
    int* end = partial_sum(a4.begin(), a4.end(), r1);
    print(r1, end, "partial_sum", " ");
    FibonacciAdapter a5(SZ);
    int r2[SZ] = {0};
    end = adjacent_difference(a5.begin(), a5.end(), r2);
    print(r2, end, "adjacent_difference", " ");
} ///:~
<style type="text/css">.csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } </style> <style type="text/css">.csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } </style>
Template Method

模板方法模式的一个重要特征是它的定义在基类中(有时作为一个私有成员函数)并且不能改动。

//: C10:TemplateMethod.cpp
// Simple demonstration of Template Method.
#include <iostream>
using namespace std;
 
class ApplicationFramework {
protected:
  virtual void customize1() = 0;
  virtual void customize2() = 0;
public:
  void templateMethod() {
    for(int i = 0; i < 5; i++) {
      customize1();
      customize2();
    }
  }
};
 
// Create a new "application":
class MyApp : public ApplicationFramework {
protected:
  void customize1() { cout << "Hello "; }
  void customize2() { cout << "World!" << endl; }
};
 
int main() {
  MyApp app;
  app.templateMethod();
} ///:~
<style type="text/css">.csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } </style>

驱动应用程序运行的“引擎”是模板方法模式。在GUI(图形用户界面)应用程序中,这个“引擎”就是主要的事件环,客户程序员只需提供customize1()和customise2()的定义,便可以令“应用程序”运行。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值