我正在研究一些源代码,我只是想知道为什么一个类(或类)经常以这种方式实现:
class EventHandler
{
...
EventDispatcher* m_Dispatcher;
virtual bool ProcEvent( EventHandler* Sender, int Task, int Event, void* Param );
...
};
class ClassA: public EventHandler
{
...
ClassA* m_Impl;
ClassA* m_Iface;
...
public:
// virtual functions
virtual bool ProcEvent( EventHandler* Sender, int Task, int Event, void* Param );
virtual void OnDataWritten(const PIOResult&) {;}
...
// sample functions
void SetImplement( ClassA* aImpl );
void SetInterface( ClassA* aIface );
ClassA* GetImplement() { return m_Impl; }
ClassA* GetInterface() { return m_Iface; }
bool GetData( list& aList );
};
// Implementation of some sample functions; Most of its function contain more
// or less the same format as below, with the return m_Impl->XXX having the same
// name as the function being defined (e.g. A::XXX)
bool ClassA::GetData( list< Data >& aList )
{
if( m_Impl )
return m_Impl->GetData( aList );
else
return false;
}
class ClassAFactory: public EventHandler
{
private:
ClassAFactory* m_Impl;
ClassAFactory* m_Iface;
protected:
virtual ClassA* MakeTransport();
virtual bool ProcEvent( EventHandler* Sender, int Task, int Event, void* Param );
virtual ClassA* CreateClassA() { return 0; }
...
};
// In some member function of ClassB (ClassB inherits ClassA)
switch( status )
{
case 1:
GetInterface()->OnDataWritten();
case 2:
// ...
};
我相信这是一些设计模式,但我不熟悉它。如果我知道它是什么,它可以帮助我理解。任何人都可以帮我指出它可能是什么或这些类的使用是什么,以便以这种方式实现?
我认为这是一些事件处理和一些工厂一起使用但我不确定。
答案 0 :(得分:2)
我猜测,但它可能是你正在寻找的“pimpl成语”吗? http://www.gamedev.net/reference/articles/article1794.asp
修改的的
带有GetData实现的扩展代码示例绝对是pimpl习语的一个例子。但是,这并不能解释m_Iface
成员。你能提供一个使用它的地方的例子吗?
的 EDIT2 的的
通过添加如何显示m_Iface的示例,很清楚我对pimpl的看法是错误的。它是一种装饰者。 m_Impl指向底层对象,而m_Iface指向最外层,因此底层对象可以进行遍历整个装饰器链的调用。这个例子有点复杂,因为ClassA都是接口类和默认实现。如果您想为类创建装饰器,则必须继承ClassA。
答案 1 :(得分:2)
我担心使用的名称不具有usual
含义,所以如果没有使用的内容或如何使用它们的例子,那就很难猜测。
你应该检查两种设计模式,大量使用这种self-recursion
(在班级*):
我担心你正在寻找那些无法模仿其中任何一种的东西。
在Decorator
中,重点是添加功能。为此,您有Interface
个派生Concrete
类和Wrapper
接口。然后各种包装器将派生Wrapper
,你可以链接它们:
Interface* interface = new Wrapper2( new Wrapper1 ( new Concrete() ) );
每个包装器都添加了一些功能,而这里我们只有完美的转发...所以它不是Decorator
。
Composite
模式不同。它的目标是隐藏您是否使用元素集合或单个元素处理。通常的示例是树:如果使用Composite
模式实现操作,则可以将操作应用于整个子树或仅应用叶节点。
再一次,这里没有这样的东西。
所以我最好的猜测是你有一个疯狂的设计(可能是一个误导的模仿一个众所周知的模式的尝试),或者你没有给我们足够的信息(源代码)来找出这个角色。无论如何,这似乎很奇怪。
*注意:在类级self-recursion
我的意思是类A
的对象指向类A
的另一个对象,但这并不意味着(当然)它指向它对同一个实例...否则我们会有一个Stack Overflow(双关语)。在SetImplementation
调用期间,这个不是同一个实例位肯定值得检查:请注意,任何循环引用都会因递归而导致死亡。
答案 2 :(得分:0)
这看起来比C ++更多。在任何面向对象的语言中,您都可以使用继承和虚函数来获得此行为。
使用指向实现类的内部指针非常好(pimpl习惯用法),但调用者通常无法访问此指针。而且我根本没有获得接口指针。
答案 3 :(得分:0)
我不确定这是否是pimpl
成语的经典示例,但如果是这样,那么重点是将接口(应该是稳定的)与实现细节分开(这应该是相对的)可以自由改变。