首先,了解“绑定”是否在编译时已知会很有用。如果是这样,我建议您查看策略类。
除此之外,我会混合使用这两种解决方案,即使用接口方法并实现一个接口,该接口充当信号/自由功能的中继器。通过这种方式,您可以拥有默认行为,您可以添加实现整个界面的自定义对象,并且基本上具有这两种方法的优点以及很大的灵活性。
这是所提出方法的基本示例,希望对您有所帮助。
#include <functional>
using namespace std;
template <class ObserverPolicy>
class Animation : public ObserverPolicy{
};
class MonolithicObserver{
public:
void play(){
state = playing;
}
void pause(){
if(playing == state)
state = stopped;
}
void stop(){
state = stopped;
}
private:
enum {playing, paused, stopped} state;
};
struct doNothing{
static void play(){}
static void pause(){}
static void stop(){}
};
struct throwException{
class noPlay{};
class noPause{};
class noStop{};
static void play(){
throw noPlay();
}
static void pause(){
throw noPause();
}
static void stop(){
throw noStop();
}
};
template <class DefaultPolicy = doNothing>
class FreeFunctionObserver{
public:
void play(){
if(playHandle)
playHandle();
else
DefaultPolicy::play();
}
void pause(){
if(pauseHandle)
pauseHandle();
else
DefaultPolicy::pause();
}
void stop(){
if(stopHandle)
stopHandle();
else
DefaultPolicy::stop();
}
void setPlayHandle(std::function<void(void)> p){
playHandle = p;
}
void setPauseHandle(std::function<void(void)> p){
pauseHandle = p;
}
void setStopHandle(std::function<void(void)> p){
stopHandle = p;
}
private:
std::function<void(void)> playHandle;
std::function<void(void)> pauseHandle;
std::function<void(void)> stopHandle;
};
void play(){}
void pause(){}
void stop(){}
int main(){
Animation<FreeFunctionObserver<> > affo;
affo.setPlayHandle(play);
affo.setPauseHandle(pause);
affo.setStopHandle(stop);
affo.play();
affo.pause();
affo.stop();
Animation<FreeFunctionObserver<throwException> > affot;
try{
affot.play();
}
catch(throwException::noPlay&){}
Animation<MonolithicObserver> amo;
amo.play();
amo.pause();
amo.stop();
}
你可以在这里试试。特别是,此示例使用策略类(因此没有“正式”定义接口,您可以“丰富”接口,就像 setPlayHandle 所做的那样)。但是,您也可以对运行时绑定执行类似的操作。