C# 设计一个类,使它不会';不要成为一个;“上帝客体”;

C# 设计一个类,使它不会';不要成为一个;“上帝客体”;,c#,java,design-patterns,oop,god-object,C#,Java,Design Patterns,Oop,God Object,我正在设计一个应用程序,它允许我在图形上绘制一些函数。每个函数都将从我将传递给这个图形类的一组点中绘制 有不同类型的点,都是从MyPoint类继承的。对于某些类型的点,它只是将它们按原样打印在屏幕上,其他点可以忽略,其他点可以添加,因此与它们相关的某种逻辑可能会变得复杂 如何实际绘制图形不是这里的主要问题。困扰我的是如何使代码逻辑使GraphicMaker类不会成为所谓的God对象 这样做很容易: class GraphicMaker { ArrayList<Point> p

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

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

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

这样做很容易:

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
            }
        }
    }
}
GraphicMaker类{
ArrayList points=新的ArrayList();
公共无效添加点(点-点){
点。添加(点);
}
公屋空置{
foreach(点对点){
如果(点为点A){
//这里有些逻辑
else if(点为点XYZ){
//…等等
}
}
}
}
你会怎么做?我觉得正确的方法是将绘图逻辑放在每个Point对象上(这样Point的每个子类都会知道如何绘制自己),但会出现两个问题:

  • 有些点需要知道GraphicObject类中存在的所有其他点,才能知道如何绘制它们自己
  • 我可以公开Graphic类中的许多方法/属性,这样所有的点都有一个对Graphic类的引用,并且可以按照他们的意愿生成所有的逻辑,但是不想拥有一个God类不是要付出很大的代价吗

  • 我将按照您的建议,让每个点负责绘制自己,并将其他点的数组传递给它:

    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
        }
    }
    

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

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

    绘图方法应引用图形对象,图形对象应具有点绘图方法中需要使用的任何内容的公共方法/属性,包括点列表(如果这是某些绘图方法需要的内容之一)


    为什么要关心在graphics类上公开方法?一旦代码增长,一些额外的可见方法比一个完成所有工作的巨大方法要容易理解得多。

    Aha!我没有想到让GraphicObject类将点列表作为参数传递给点的Draw()方法。这似乎是一个非常好的主意。虽然我仍然不确定在GraphicObject类中公开所有可能相关的属性是否是最好的,因为可能在将来,我的点绘制逻辑不仅需要所有点的列表,还需要其他一些东西。如果我通过列表而不是公开属性,我将不得不将新参数添加到point的Draw()方法中。这实际上取决于GraphicsObject的工作方式,但我认为我不希望将其传递到Draw方法中(我可能错了,它与上下文相关,我没有完整的上下文)如果你发现你需要GraphicsObject可以提供的一个子集信息,加上所有的点,我会考虑创建一个类,纯粹是为了传递到包含GraphicsObject需要的点和额外的东西列表的绘图方法。.但是-如果GraphicsObject与绘图有关,则将其传递给其他组件。请查看现有系统以获取灵感。在Swing中,每个组件都有自己的paint(),该paint()传递给Graphics对象。容器/布局/组件方法允许某些组件影响其他组件(包含)组件。但是,我不会将列表传递给点的绘图。我会向GraphicsObject添加一个查询,返回其他点的列表。例如具有特定类型、在一定距离内、相同颜色的点等。是的,我认为你是对的。拥有一些公共属性/方法无疑是一种方式。
    public void DoDrawing() {
        foreach (Point point in points) {
            point.Draw(points);
        }
    }