该问题适用于qt库的类QGraphicsView
。
但是,问题更为笼统。所以,如果我没有错过qt中的任何特殊机制,可以在不知道qt的情况下进行讨论。
我正在继承QGraphicsView
以添加我需要的一些功能。
例如。我有ScalableView
,PannableView
和LabeledView
来添加独立功能。
我现在使用的子类在以下意义上是线性的:
ScalableView
源自QGraphics
视图。
PannableView
源自ScalableView
视图。
LabeledView
源自PannableView
视图。
由于这些功能是独立的,因此存在设计缺陷。
应用装饰器模式来解决这个问题对我来说似乎很合适。
问题是,QGraphicsView
不是接口,并且不存在像 QAbstractGraphicsView 这样的接口类。所以,对我而言,尚不清楚该模式是如何实现的。
另一个想法是使用模板。因此,我可以从模板T
派生每个视图。然后,我可以制作ScalableView<PannableView<LabeledView>>>
。
你认为有更好的解决方案吗?在这种情况下,我更喜欢一种实现装饰器模式的方法,因为我想避免使用会增加编译时间的许多模板类。
答案 0 :(得分:3)
Qt风格的一个简单解决方案是创建一个派生自QGraphicsView
的类,并且只具有控制其行为的标志(无论是可扩展的,可扩展的,标记的等)。这些行为的实现仍然会被分解为方法,所以它就是
不像看起来那样单片。
装饰器模式当然可以通过定义中间(垫片)接口来轻松实现。 QGraphicsView
不需要实现该接口 - 该接口仅供装饰器使用。
深度继承的问题在于,无法精确控制行为的相互作用。您拥有的唯一控件是事件处理的顺序。这可能恰好足够了,但我有点担心。没有点缀的装饰模式分享了这个问题。
答案 1 :(得分:1)
在不知道完整设计的情况下,这可能会或可能不会起作用,但也许这会有所帮助。
一种可能的方法是封装QGraphicsView并创建提供所需的不同功能的委托对象。然后,代表将负责提供图形视图和转发消息的接口。
这意味着为不同类型的功能创建不同的委托;一个ScalableDelegate,一个PannableDelegate和一个LabeledDelegate。
由于委托是单独的对象而不是从QGraphicsView继承,因此您可以通过在图形视图上安装事件过滤器来获得许多功能。
然后,它们不是与GraphicsView交互的对象,而是通过相关的委托进行通信。
如果限制太多,您可能需要从QGraphicsView继承以创建具有所需功能的视图,然后使用委托根据需要公开所需的功能。