对于我的软件工程面向对象设计类,我们的任务是实现一个简单的“Paint”应用程序,它可以绘制简单的东西,如椭圆,矩形,直线,自由曲线和文本。
我真的想在这里寻找黄金,并提出一个非常干净和优雅的架构,因为我们需要支持诸如打印,保存和导出到图像之类的东西,我希望能够做到所以用最小的努力。
到目前为止,我有三个级别的“层级”:
Ellipse
,Rectangle
,Line
,Textbox
和Freeform
,全部继承自我的自定义Shape
类GraphicsModifier
,允许类更改Graphics2D
对象
StrokeStyle
描述了如何使用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; DR:
给定一系列以不同方式绘制的对象,以及以不同的容量应用于它们的样式,如何使用良好的面向对象设计绘制它们?
答案 0 :(得分:1)
答案 1 :(得分:1)
你是对的 - 它感觉有点脏:)
原因是如果您真的要使用策略模式,则需要替换现有的子类。所以不再有Rectangle类,只有一个Shape的策略设置为RectangleDrawer。然后就不需要那些丑陋的ifs,因为没有必要映射任何东西。
在这种情况下,我认为策略不是您的最佳选择。当你需要动态地改变行为时,策略是很好的,而且一旦绘制了一个正方形,我就会在你的程序中猜测它永远不会变成一个圆圈。
答案 2 :(得分:0)
如果你要继承heirarchy,那就太平了。
你真的想要这样的东西:
Drawable
+-Shape
| +-Rectangle
| +-etc.
+-FreeForm
+-etc.
或者,保持平坦的层次结构,并使用虚拟render()
方法。渲染应该只返回一个位图,然后你的绘制方法可以是:
void draw(Shape s) {
graphics.Draw(s.render(), s.x, s.y);
}
然后您可以在每个类中覆盖render
,以便Rectangle生成纯色位图,Ellipse返回一个在外部透明但在中心呈椭圆形的纯色位图,等
社区Wiki,如果有人觉得他们有需要添加的东西,他们就可以直接添加它。
答案 3 :(得分:0)
JHotDraw值得参考以解决您的问题。其原始作者是Erich Gamma,Design Patterns: Elements of Reusable Object-Oriented Software的作者之一。