介体模板执行类型转换

时间:2012-11-21 01:51:29

标签: c++ templates observer-pattern

我正在评估观察者模式的实现策略,其中一个要求是基类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;
}    

唯一的问题是我有一种直觉,认为有更好的解决方案;很大程度上,我不记得曾经在任何来源或图书馆看过像上面那样的调解员课程 - 但可能是我缺乏经验。

有人可以建议更好地解决上述问题吗?

0 个答案:

没有答案