如何使调用代码对被调用的代码一无所知

时间:2012-01-01 04:51:00

标签: c++ design-patterns boost

基于Beyond the C++ Standard Library: An Introduction to Boost,第32页的使用Boost.Bind和Boost.Function 一节,作者说明了我们可以将调用代码与底层实现代码分离的方法之一。

  

将图形用户界面(GUI)与详细信息分开时   处理来自用户的动作(事件),某种类型的回调是   几乎总是使用。如果此回调机制基于功能   指针,很难避免类型的严重限制   与回调一起使用,这反过来又增加了添加的风险   表示和业务逻辑之间的耦合。我们可以避免   这完全是通过使用Boost.Function,并结合使用   支持参数绑定的库,我们可以提供上下文   轻松调用函数。这是最常见的一种   使用这个库来分离业务逻辑的知识   表示层。

class tape_recorder {
public:
  void play() {
    std::cout << "Since my baby left me...\n";
  }

  void stop() {
    std::cout << "OK, taking a break\n";
  }

  void forward() {
    std::cout << "whizzz\n";
  }

  void rewind() {
    std::cout << "zzzihw\n";
  }

  void record(const std::string& sound) {
    std::cout << "Recorded: " << sound << '\n';
  }
};

typedef boost::function<void()> command;

tape_recorder tr;

command play(boost::bind(&tape_recorder::play,&tr));
command stop(boost::bind(&tape_recorder::stop,&tr));
command forward(boost::bind(&tape_recorder::stop,&tr));
command rewind(boost::bind(&tape_recorder::rewind,&tr));
std::string s="What a beautiful morning...";
command record = boost::bind(&tape_recorder::record,&tr,s));


// Invoked from some GUI control...
  if (play) {
    play.execute();
  }

  // Invoked from some scripting client...
  stop.execute();
  

使用Boost.Function和Boost.Bind,可以实现   解耦使得调用代码可以知道   没有关于被调用的代码。结合起来非常有用   这两个库就是这样的。

问题&GT;我理解上面的代码是如何工作的,但我仍然感到困惑的是如何将调用代码与实际实现分离,就像作者最初想要存档一样。调用代码(即所有类型的命令)仍然需要知道tape_recorder的成员函数。那么解耦在这里究竟意味着什么?

1 个答案:

答案 0 :(得分:1)

他所说的只是Boost库为“回调”提供了一种机制;他给出了一个例子,说明如何使用具有一组通用功能的特定类“录音机”(“打开”,“播放”,“停止”等)。你可以想象写一个不同的类(智能手机?)可以实现相同的功能。

这些链接可能有所帮助:

http://www.codeproject.com/KB/library/BoostBindFunction.aspx

http://www.crystalclearsoftware.com/cgi-bin/boost_wiki/wiki.pl?action=browse&diff=1&id=Boost.Function,_Boost.Bind,_And_Member_Functions