绘制形状的良好架构

时间:2010-12-10 03:56:53

标签: java oop drawing

对于我的软件工程面向对象设计类,我们的任务是实现一个简单的“Paint”应用程序,它可以绘制简单的东西,如椭圆,矩形,直线,自由曲线和文本。

我真的想在这里寻找黄金,并提出一个非常干净和优雅的架构,因为我们需要支持诸如打印,保存和导出到图像之类的东西,我希望能够做到所以用最小的努力。

到目前为止,我有三个级别的“层级”:

  1. 形状类:EllipseRectangleLineTextboxFreeform,全部继承自我的自定义Shape
  2. 样式类,每个样式实现GraphicsModifier,允许类更改Graphics2D对象
    • StrokeStyle描述了如何使用StrokePaint个对象绘制形状笔划
    • FillStyle使用Paint对象
    • 描述填充
    • TextStyle基本上是AWT字体类的包装器,可以轻松修改字体大小,样式和面孔。
  3. 绘图课程
  4. 现在,我被困在应该如何实施我的绘图课程。

    我最初的想法是有类似

    的东西
    class DrawingObject {
        StrokeStyle stroke;
        FillStyle fill;
        TextStyle text;
        Shape shape;
    
        void draw(Graphics2D g) {
            //????
        }
    }
    

    问题在于,如果shapeFreeform,我只需要应用stroke并循环遍历曲线中的每个点并单独绘制它。如果shapeRectangleLineEllipse,我只需要应用strokefill,并使用g.draw(Shape) }。如果shapeTextbox,我需要应用所有三个strokefilltext,并使用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:
    给定一系列以不同方式绘制的对象,以及以不同的容量应用于它们的样式,如何使用良好的面向对象设计绘制它们?

4 个答案:

答案 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 GammaDesign Patterns: Elements of Reusable Object-Oriented Software的作者之一。