以不会成为“上帝对象”的方式设计课程

时间:2010-04-07 02:48:09

标签: c# java design-patterns oop god-object

我正在设计一个允许我在图形上绘制一些功能的应用程序。每个函数都将从我将传递给此图形类的一组点中提取。

有各种各样的点,都是从MyPoint类继承的。对于某些点,它只是将它们按原样打印在屏幕上,其他点可以被忽略,其他的则被添加,因此存在某种与之相关的逻辑可能变得复杂。

如何实际绘制图形不是这里的主要问题。困扰我的是如何使代码逻辑使得这个GraphicMaker类不会成为所谓的上帝对象。

制作这样的东西很容易:

class GraphicMaker {
    ArrayList<Point> points = new ArrayList<Point>();

    public void AddPoint(Point point) {
        points.add(point);
    }

    public void DoDrawing() {
        foreach (Point point in points) {
            if (point is PointA) {
                //some logic here
            else if (point is PointXYZ) {
                //...etc
            }
        }
    }
}

你会怎么做这样的事情?我有一种感觉,正确的方法是将绘图逻辑放在每个Point对象上(因此Point中的每个子类都知道如何绘制自己)但是出现了两个问题:

  1. 有些点需要知道GraphicObject类中存在的所有其他点才能知道如何绘制自己。
  2. 我可以从Graphic类中创建很多方法/属性,这样所有的点都可以引用Graphic类,并可以根据需要制作所有的逻辑,但这不是一个很大的代价。为不想上神课而付出代价?

2 个答案:

答案 0 :(得分:4)

我会像你建议的那样做,并让每个点负责绘制自己,将其他点的数组传递给它:

interface ICanDraw {
    void Draw(ArrayList<Point> allPoints);
}

public abstract class Point : ICanDraw {
    ...
}

public PoniePoint : Point {
    public void Draw(ArrayList<Point> allPoints) {
        // do drawing logic here
    }
}

对于您的GraphicMaker:

public void DoDrawing() {
    foreach (Point point in points) {
        point.Draw(points);
    }
}

(我的Java有点生疏,所以这可能不是100%语法上正确的Java,但我认为它传达了我的建议。)

答案 1 :(得分:3)

你是正确的,Point的每个子类都应该有自己的绘图方法覆盖基Point类中的绘图方法。

绘图方法应该引用图形对象,该图形对象应该具有需要在点绘制方法中使用的任何事物的公共方法/属性,包括点列表,如果这是某些事情之一绘图方法需要。

为什么您担心在图形类上制作公共方法?一旦代码增长,一些额外的可见方法比一个完成所有事情的巨大方法更容易混淆。