我正在评估观察者模式的实现策略,其中一个要求是基类Subject
类到达Event
类的派生(具体)类中的方法。 / p>
在原型实现中,我已在具体事件类中获得此代码:
// a concrete event
class evZoom : public AbstractEvent
{
public:
virtual void Fill( Subject *aZoomManager)
{
mRatio = dynamic_cast<ZoomManager *>(aZoomManager)->mRatio;
}
int mRatio;
};
现在我对每个concreate事件必须执行此类型转换的事实感到困扰。
换句话说,我关心代码的简单性和简洁性,我宁愿具体的类(其中有很多)有更优雅的代码,用更复杂的基类代码交换(有一个代码)
因此我提出的解决方案是使用中介(即基类和具体类之间的模板)模板进行类型转换。
完整实现如下:
// For Dec
class Subject;
// A non template abstract base class for the Subject class to work with.
class AbstractEvent
{
public:
virtual void Fill ( Subject *aSubject ) = 0;
};
// A mediator class to do the type casting
template < class TSubject >
class Event : public AbstractEvent
{
public:
// This is where we do the type cast.
virtual void Fill ( Subject *aSubject )
{
TSubject *iSubject = dynamic_cast<TSubject *>(aSubject);
// Somehow the compiler knows to call the abstract method below, but if
// we change its name we'll get an infinite loop - cranky.
Fill( iSubject );
}
// And a new abstract method to be implemented by concrete events.
virtual void Fill ( TSubject *aSubject ) = 0;
};
// The subject base class
class Subject
{
public:
// virtual destructor to make this class polymorphic
// so we can cast it dynamically.
virtual ~Subject() { }
void Subscribe( AbstractEvent *aEvent )
{
aEvent->Fill( this );
}
};
// A concrete subject class.
class ZoomManager : public virtual Subject
{
public:
int mRatio;
};
// The concrete event
class evZoom : public Event< ZoomManager >
{
public:
virtual void Fill( ZoomManager *aZoomManager )
{
mRatio = aZoomManager->mRatio;
}
int mRatio;
};
int main(int argc, const char * argv[])
{
ZoomManager iZoomManager;
evZoom *iEvent = new evZoom();
iZoomManager.Subscribe( iEvent );
return 0;
}
唯一的问题是我有一种直觉,认为有更好的解决方案;很大程度上,我不记得曾经在任何来源或图书馆看过像上面那样的调解员课程 - 但可能是我缺乏经验。
有人可以建议更好地解决上述问题吗?