我正在为各种目标编写一个跨平台UI工具包,其中一些是嵌入式的。这些平台中的一些支持"保留"渲染模式,其中一些更"直接",所以我认为我的视觉效果有两个树-伪代码:
abstract class Visual
{
Visual( Widget widget ) { this.widget = widget; }
}
abstract class RetainedVisual : Visual
{
abstract void Setup( Renderer r );
abstract void Teardown( Renderer r );
}
abstract class ImmediateVisual : Visual
{
abstract void Paint( Renderer r );
}
到目前为止一切顺利。但现在我也有ContainerVisual
类编码小部件层次结构:
abstract class ContainerVisual : Visual
{
void AddChild( Visual child ) {}
}
这有点迫使我有一个ImmediateContainerVisual
和RetainedContainerVisual
类开始看起来臃肿。对更好的设计有什么想法?
最好的选择是将这三个类合并为同一个Visual class:
class Visual {
Visual(Widget w);
bool SupportsSetupTearDown();
bool SupportsPaint();
abstract void Setup(Renderer r);
abstract void TearDown(Renderer r);
abstract void Paint(Renderer r);
};
那么容器部件就不会有任何问题了。所有的视觉效果都应该实现这两种渲染方法,当目标发生变化时,系统将开始调用不同的函数。这也允许有条件地不以一种方式实现,并且可以构建从SetupTearDown转换为Paint和从Paint转换为SetupTearDown的特殊视觉效果。
在没有更多信息的情况下很难决定走哪条路:就功能而言,保留/立即有什么区别?容器是做什么的?
但是,在c++中,你可以考虑使用类模板来处理Container:
template <typename BaseType>
class ContainerVisual : public BaseType
{
public:
void AddChild(BaseType & /*or smart pointer or whatever*/ child ) {}
}