用于绘制形状
对于我的软件工程面向对象设计类的良好架构,我们的任务是实现一个简单的“画图”程序,可以绘制简单的事情像椭圆,矩形,线条,*形式的曲线和文本。用于绘制形状
我真的想在这里找到黄金,并且想出了一个非常干净优雅的架构,因为我们需要支持诸如打印,保存和导出到图像之类的东西,并且我希望能够以最小的努力做到这一点。
到目前为止,我拥有类三 “层次”:
- Shape类:
Ellipse
,Rectangle
,Line
,Textbox
和Freeform
,从我的自定义所有继承Shape
类 - 风格类,每一类的其实现了
GraphicsModifier
,其允许该类改变对象对象-
StrokeStyle
描述了形状的stro柯应绘制,用Stroke
和Paint
对象 -
FillStyle
描述的填充,具有Paint
对象 -
TextStyle
基本上是AWT的字体类的包装,允许字体大小,样式,和面容易变形。
-
- 绘图类
现在,我坚持我的绘画课应该如何实现。
我最初的想法是有东西像
class DrawingObject {
StrokeStyle stroke;
FillStyle fill;
TextStyle text;
Shape shape;
void draw(Graphics2D g) {
//????
}
}
的问题是,如果shape
是Freeform
,我需要通过在曲线的每个点只stroke
和循环应用,并分别绘制。如果shape
是Rectangle
,Line
或Ellipse
,我只需要应用stroke
和fill
,并使用g.draw(Shape)
。如果shape
是Textbox
,我需要应用这三个stroke
,fill
和text
,并使用g.drawString()
。
它发生,我认为这可能是应用策略模式的好地方,打开的shape
子类:
if (shape instanceof Freeform) {
strategy = new FreeformDrawer(shape);
} else if (shape instanceof Rectangle || ...) {
strategy = new NormalDrawer(shape);
} else if (shape instanceof Textbox) {
strategy = new TextboxDrawer(shape);
}
strategy.draw(g);
(我想我可以在课上使用的小反射魔法switch
名字也一样,但这是题外话)
但不知何故,这感觉有点脏。
你会如何解决这个问题?我是否在谈论这个错误?策略是一个好主意吗?
如果重要,我使用Java和Swing来实现这一点,但理论上它应该适用于任何OO语言/框架。
TL;博士:
考虑以不同的方式绘制了一堆的对象,而获得不同的能力,适用于他们的风格,你将如何吸引他们,用良好的面向对象设计的?
如果你打算继承heirarchy,它太平。
你真的想要的东西,如:
Drawable
+-Shape
| +-Rectangle
| +-etc.
+-FreeForm
+-etc.
或者,留着平层次结构,并使用虚拟render()
方法。渲染应该只返回一个位图,然后你的平局方法是这样的:
void draw(Shape s) {
graphics.Draw(s.render(), s.x, s.y);
}
然后,您可以覆盖每个类的render
,使矩形产生单色位图,椭圆返回一个位图在外部是透明的,但在中心椭圆形的纯色,等等。
社区Wiki,以便如果任何人觉得他们有东西要添加,他们可以直接前进并添加它。
JHotDraw是值得引用解决您的问题。它的原作者是Erich Gamma,作者之一Design Patterns: Elements of Reusable Object-Oriented Software。
谢谢,我会给你一个看看。 – 2010-12-10 23:52:43
你是对的 - 它确实感觉有点脏:)
的原因是,如果你真正使用的策略模式你需要替换你现有的子类。所以不会再有Rectangle类,只会有一个Shape,其策略设置为RectangleDrawer。那么就不需要那些丑陋的ifs,因为不需要映射任何东西。
在这种情况下,我不认为策略会是你最好的选择。当你需要动态改变行为时,策略非常适用,一旦绘制了正方形,我就会在程序中猜测它永远不会变成一个圆圈。
那么,我简化了一下我的例子。这几乎是我所拥有的层次结构,除了我的顶层是`Shape`,然后`Rectangle`,`Ellipse`,`Line`都从`RectangularShape`继承,它扩展了`Shape`。 `Freeform`和`Textbox`直接延伸`Shape` – 2010-12-10 04:08:40
此外,我想保留我的形状只关注自己的属性,而不是自己画。如果我按你的建议做,我的形状现在“知道”位图,在语义上它们不应该。 – 2010-12-10 04:11:15