我正在使用 vector 绘图应用程序(在Java中),并且在模型类与 View / Controller 类之间的分离方面处于挣扎中。

一些背景:

您可以绘制不同的形状:
矩形,直线和扇形段

有4种工具可以操纵 Canvas 上的形状:
缩放工具,移动工具,旋转工具和变形工具

对于这个问题,变形工具是最有趣的一个:
它使您可以通过拖动形状的一个点并调整其他属性来更改形状,如下图所示:

这些转换规则对于每种形状都是不同的,我认为它们是模型业务逻辑的一部分,但从某种意义上讲,它们需要公开给 View / Controller (工具类),以便可以应用正确的规则。

此外,形状通过不同的值在内部表示:
-矩形存储为中心,宽度,高度,旋转
-线被存储为起点和终点
-扇形段存储为中心,半径,角度1,角度2

我计划在将来添加更多形状,例如星星,气泡或箭头,每个形状都有自己的控制点。

我还计划在将来添加更多工具,例如旋转或缩放形状组。

每个工具的控制点都不同。例如,使用缩放工具时,您无法捕获中心点,但是每个缩放控制点都需要与一个枢轴点(或多个枢轴点)相关联,以便用户选择。

对于简单的形状(如矩形,直线和扇形),该类的每个实例的控制点都相同,但 future 形状(如贝塞尔曲线或星形(具有可配置的峰值数))每个实例将具有不同数量的控制点。

那么问题是,有什么方法可以很好地建模和实现这些控制点?

由于每种工具的工具略有不同,并带有一些工具/ Controller 特定的数据,因此它们以某种方式属于工具/ Controller 。但是,由于它们也针对每种形状,并且具有非常重要的域逻辑,因此它们也属于模型。

我想避免在每次添加一个工具或形状时为每种工具/形状组合添加一种特殊类型的控制点的组合爆炸。

更新:再举一个例子:将来可能会出现一个我想支持的新形状的想法:圆弧。它与饼图段相似,但是看起来有些不同,并且在拖动控制点时的行为完全不同。

为了实现这一点,我希望能够创建一个实现我的Shape接口(interface)的ArcShape类并完成它。

最佳答案

基本注意事项

首先,让我们为简单起见进行一些定义。
Entity是域模型对象,它定义了所有的结构和行为,即逻辑。EntityUI是表示UI中Entity的图形控件。

因此,基本上,对于Shape类,我认为ShapeUI必须非常了解Shape的结构。该结构主要由我猜想的控制点组成。换句话说,有了关于控制点的所有信息(将来可能是 vector ),ShapeUI将能够在UI上绘制自己。

初步建议

我对Shape类的建议是,Shape类定义了所有行为。 ShapeUI类将了解Shape类,并保留对其表示的引用,通过它可以访问控制点,并能够操纵它们,例如,控制点。设置他们的位置。 Observer模式只是要求在此上下文中使用。特别地,Shape类可以实现Observable,并且ShapeUI将实现Observer并订阅相应的Shape对象。

所以基本上在这种情况下会发生什么,ShapeUI对象将处理所有UI操作,并负责更新Shape参数,例如控制点位置。然后,一旦位置更新发生,Shape对象就会在状态更改时执行其逻辑,然后盲目地(不知道ShapeUI)将更新后的状态通知给ShapeUI。因此,ShapeUI相应地将绘制新状态。在这里,您将获得低耦合模型和 View 。

至于Tools,我个人的观点是每个Tool必须知道如何操作每种类型的Shape,即每个形状操作逻辑必须在Tool类内部实现。对于 View 和模型的解耦,与Shape几乎相同。 ToolUI类处理光标的单击位置,单击的ShapeUI,单击的控制点等。通过获取此信息,ToolUI将其传递给适当的Tool对象,然后该对象将基于接收的参数。

处理不同的形状类型

现在,当谈到以自己的方式处理不同的ToolShape时,我认为Abstract Factory模式介入了。每个工具都将实现一个Abstract Factory,在此我们将为每种类型的Shape提供操纵实现。

摘要

根据我的建议,这是领域模型(Domain Model)草案:

为了从我的建议中得到整个想法,我还发布了特定用例的序列图:

用户使用ToolUI单击ShapeUIControlPointUI

关于java - 在绘图应用程序中分离模型和 View / Controller ,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/30155807/

10-10 09:13