平时口头上说的“Adapter Pattern”是指,库代码与实际应用端的功能需求不一致,但确实存在一部分的库代码可以重用,于是把库代码适配成所需的功能接口,于是“生出”一个适配器类,给某一个/或多个库中的作了一次功能包装,顺便补上没有的功能,所以,往往有如下这样的code:

// windowInterface是库的接口类,window_win32/window_qt/window_gtk是库中的实现类的情况下

class MyWindowAdaptor: public windowInterface, protected window_win32
{
public:
   //一些所需的接口函数...

  void resize(int x, int y) {   // eg.
      // ...
      window_win32::resize(x,y);
   }
};
或是
class MyWindowAdaptor: public windowInterface{
public:
   //一些所需的接口函数...

  void resize(int x, int y) {   // eg.
      // ...
      winImpl_.resize(x,y);
   }
private:
  window_win32 winImpl_;
};

而pixeltoastor里面使用了一丁点的宏,完成了类似的事情,并且由此得到了平台可移植性,把平台相关的实现代码约束在编译期,使得用户代码更为clear,大致的轮廓如下:

// window interface
struct WindowAdaptor {
  virtual ~WindowAdaptor() {}

  virtual void set(int ) =0;
  virtual int get() =0;
  virtual void update() =0;
  virtual void resize(int , int ) =0;
};

// device interface
struct GraphicAdaptor {
  virtual ~GraphicAdaptor() {}

  virtual bool beginScene() =0;
  virtual void endScene() =0;
  virtual void clearScene() =0;

  virtual void drawTriangle(Tri* pStart, unsigned count) =0;
};

 


// platform config macro
#ifdef WIN32
# define USE_OGL
# define USE_DX9
#elif LINUX
# define USE_OGL
#endif


// window implement
#ifdef WIN32
class Window_win32: public WindowAdaptor {
public:
  virtual ~Window_win32() {}

  virtual void set(int )
  { }

  virtual int get()
  { return 0; }

  virtual void update()
  { }

  virtual void resize(int , int )
  { }

  // ...
};
#define Window Window_win32
#endif

#ifdef LINUX
class Window_Linux: public WindowAdaptor {
  // implement code...
};
#define Window Window_Linux
#endif

// device implement
#ifdef USE_DX9
class GraphicDevice_Dx9: public GraphicAdaptor {
  // implement code...
};
#define GraphicDx9 GraphicDevice_Dx9
#endif

#ifdef USE_OGL
class GraphicDevice_OGL: public GraphicAdaptor {
  // implement code...
};
#define GraphicOGL GraphicDevice_OGL
#endif

 

/*  --------------------user code------------------------
// Display
class Display: public Window, public GraphicDx9 {
};

int main()
{
  Display disp;
  //...

  return 0;
}
*/

以上只是表示了逻辑结构,同时其物理结构也想象的出了!
这里保证了类型安全,不失灵活性与健壮性,却引入了可以接受的隐含的名称冲突,像这样的idom可以应用到与具体平台或设备相关的programming任务上,如:音频处理模块、输入设备模块。

{ Message("新春愉快!", "^o^"); }