我有一些类有一个名为Tool的基类。 在表单中,我有一个工具引用,其中包含所提到的类的一个实例。 当表单上发生MouseDown事件时,我调用当前的工具方法ex。 “CurrentTool.MethodWhenMouseDown()”。
大多数工具都有3种方法:
MethodWhenMouseDown()
MethodWhenMouseUp()
MethodWhenMouseMove()
但是有一两个班级只有:
MethodWhenMouseDown()
现在哪个更好:
1.要在Tool中使用所有三个方法,而不需要它们的类只调用空方法。
2.实现接口ex。 IMouseMoveListener只能由发生MouseMove事件时需要执行的类实现。这样,如果发生MouseMove事件,我们会问:
if(CurrentTool is MouseMoveListener)
{
(CurrentTool as IMouseMoveListener).MethodWhenMouseMove();
}
其他信息:
该程序就像油漆女士 - 工具是刷子,铲斗(不需要MethodWhenMouseMove的那个),LineTool等。
在我的PaintForm中,我有一个abstrac基类工具的引用,它存储一个派生类的instace。发生事件的事情是pictureBox。
您是否考虑过工具订阅的活动? - CodesInChaos
我认为在形式上有一个方法是一种好习惯,它会在evet发生后调用,并且该方法调用CurrentTool的siutable方法。例如:
void MouseMoveSubscriber(object sender, MouseEventArgs e)
{
CurrentTool.MethodWhenMouseMove(e);
}
我假设每次将CurrentTool更改为一个不好的做法时,订阅和取消订阅CurrentTool的方法?
我还考虑过在Form中使用所有工具引用,并且每个工具都会订阅该事件,并且没有需要unubscrinig。我认为最大的缺点是每个工具都需要检查它是否是CurrentTool
你怎么想的?感谢您的帮助。
答案 0 :(得分:2)
性能不是问题(当用户点击时,不必要地调用空函数的开销没有意义),所以这实际上是关于编码的简易性和代码清晰度/复杂性/可维护性。
所以我会尽量保持简单。
我会实现一个带有空实现的基类,因为它简洁明了。它需要派生类中的最少代码才能获得所需的结果。它也是有意义的(如果你没有覆盖点击上传,你基本上是说“当点击一个鼠标时我不想做任何事情”)。
下一个选项是为鼠标向上/向下/点击提供事件,并且派生类可以根据需要订阅事件。使用事件是一种标准模式,但它有一个缺点,你必须搞乱丑陋的订阅和取消订阅调用。这样做的好处是,如果你公开它们,这些事件可以由任何人处理,而不仅仅是派生类。
我会避免使用接口和转换 - 对我来说这感觉就像一个笨重的方法 - 所有它真正实现的是将“空函数”方法分解为多种不同类型,而不是简单的3种虚拟方法。而不是仅仅调用方法并知道它们将起作用,你必须首先进行大量的类型转换和检查 - 它看起来很混乱。
修改强> 既然你已经在这个问题上添加了一些内容,我就重新阅读了它,另一种可能性让人想起:创建一个基础工具类,它提供所有派生类需要覆盖的虚拟MouseDown处理程序。所有常规工具都可以从中获得。
另一个DragTool类可以派生为一个中间类,它可以添加特殊拖动工具所需的MouseMove和MouseUp处理程序。
即
ToolBase (abstract MouseDown)
|
+- ClickTool1
+- ClickTool2
+- DragToolBase (abstract MouseMove + MouseUp)
|
+- DragTool1
+- DragTool2
这意味着您的任何工具都不会有空实现。
答案 1 :(得分:1)
在不知道你的场景的情况下,我会选择接口和基类的组合:
基类使用空虚方法实现所有接口。基类是纯粹的便利构造。如果工具类想要从基类继承但不需要该方法,则它不会覆盖它。
在使用工具的代码中,您将使用接口工作。像这样,其他类可以直接实现您的接口。你可以在没有任何牺牲的情况下获得最大的灵活性。
var mouseMoveListener = CurrentTool as IMouseMoveListener;
var mouseDownListener = CurrentTool as IMouseDownListener;
// ...
if(mouseMoveListener != null)
mouseMoveListener.MethodWhenMouseMove();
if(mouseDownListener != null)
mouseDownListener.MethodWhenMouseDown();
请注意:我仅使用as
而不是is
与as
结合使用。
答案 2 :(得分:0)
这取决于实际情况。但在您的特定情况下(UI事件)我认为具有空处理程序(虚方法)的基类比许多接口更好。实际上你的所有工具都将继承一些ToolBase。调用代码将更小更简单,无需转换为接口。