画布形状模型的继承与组合?

mem*_*und 5 java oop java-canvas

对于以下模型,您更喜欢继承还是组合:

  • 我想在 a 上绘制对象canvas,每个对象代表一个数据对象
  • 把它想象成一个状态机图:在它们之间Ellipses表示States,Lines表示。connections/transitions对象表示本身永远不会改变,即 aState将始终由 a 显示ellipse。但绘制的方式ellipse应该有所不同,例如,对于选择,它应该具有不同的颜色,而拖动它可能应该有一个 Alpha 通道,等等。

从设计的角度来看, anellipse不是 a state, aline也不是 a transition。无论如何,将两个对象组合起来是合适的,以便能够将它们收集在一个对象中List<Shape>shape.draw()在每个对象上执行。

现在可以有 2 个设计模型,而我认为 2 个类始终是相同的:

interface Shape {
    void draw();
}
abstract class Figure implements Shape {
    //basic vars like start and end coordinates
    int x0, y0, x1, y1;
}
Run Code Online (Sandbox Code Playgroud)

遗产:

abstract class State extends Figure {
    String name;
}
class Rectangle extends State {
    @Override void draw();
}

class Line extends Figure;
class Transition extends Line
Run Code Online (Sandbox Code Playgroud)

尽管从设计的角度来看, arectangle不是 a State, astate也不是 a figure,但就绘图上下文而言,这可能是可行的。shapes因为我可以继承处理、绘图等所需的大部分内容。

或组成:

abstract class State {
    String name;
}

class Rectangle extends Figure {
    private State state;
    @Override void draw();
}
class Line extends Figure {
    private Transition transition;
    @Override void draw();
}
Run Code Online (Sandbox Code Playgroud)

所以Rectangle+Line将是我的对象的包装。

矩形和直线应该扩展状态和转换,还是包含它们?

或者,也许还有我没有看到的第三种设计选项。期待您的想法。

jef*_*eff 2

所以,这是我的想法,但对于大多数设计问题,很少有一个“正确”的答案。

就像你说的,状态不是矩形,过渡也不是直线。我们可以画一条线和/或一个矩形,以类似的方式处理它们可能会有一些好处。所以我可以将这些陈述转化为一个简单的设计:

public interface Drawable 
{
  public void draw();
  public Position getPos();
}

public class Rectangle implements Drawable ...
public class Line implements Drawable ...
Run Code Online (Sandbox Code Playgroud)

现在,状态和转换可以由这些 Drawable 来表示。您听说过单一职责原则吗?基本上正如它听起来的那样,一个对象应该负责做一件“事情”。矩形和直线知道如何绘制自己。状态和转换可能在您的系统中还有一些其他工作要做。

public interface Figure 
{
   public Drawable getDrawable();
}

public class State implements Figure
{
   private Rectangle rect;

   public Drawable getDrawable() { return rect; }

   //... State's real "work" below
}

public class Transition implements Figure
{
   private Line line;
   // you get the idea
}
Run Code Online (Sandbox Code Playgroud)

在小型/简单的系统上,SRP 的优势可能会丢失,但我们的想法是,我们将渲染与其他系统逻辑分开。我们将功能分离得越多,当需要进行更改时系统就会越不脆弱。