据我了解,如果您经常在类层次结构中使用向下转换,那就不好了。
我同意这一点,但是该规则有什么异常(exception)情况?
这就是我的图形编辑器设计的薄弱之处:我有两个层次结构,其中几何图形层次结构与图形基元分离。像这样:

public class GeometricPrimitive {...}
public class RectangeGeometric: Geometric Primitive {...}
public class GraphicPrimitive {...}
public class Rectangle: GraphicPrimitive {
 private RectangleGeometric figure;
 ...
}

因此,每个具体的图形类都封装了具体的几何类的实例。 是正确的方法,还是我更喜欢通用的方法? -不幸的是,在这种情况下,将使用向下转换:
public class GraphicPrimitive {
   protected GeometryPrimitive figure;
   ....
}

public class Rectangle: GraohicPrimitive {

        public Rectangle(Color c, TwoDPoint leftHighPoint, TwoDPoint rightLowPoint):
            base(new RectangleGeometric(leftHighPoint.Point2D, rightLowPoint.Point2D), c) {   }

        #region Geometric Properties

        public TwoDPoint LeftTopCorner {
            get { return new TwoDPoint(base.color, (base.figure as RectangleGeometric).LeftTopCorner); }
        }

        public TwoDPoint RightBottomCorner {
            get { return new TwoDPoint(base.color, (base.figure as RectangleGeometric).RightBottomCorner); }
        }

最佳答案

尽管您的问题缺少有关应用程序的较大上下文,这些上下文可以帮助给出特定的答案,但我将尝试向您提供一些有关如何使用您的代码来实现此想法的想法。

我将从反转GeometryPrimitive和GraphicPrimitive关系开始。我将GeometryPrimitive层次结构视为构成抽象场景图的域对象,并将GraphicPrimitive层次结构视为低级 View 组件,这些低层 View 组件将GeometryPrimitive转换为适合于绘制某种图形上下文的一组像素。 GeometryPrimitive子类保存描述自身所需的所有状态信息,但不包含将该描述转换为像素的逻辑。 GraphicPrimitive子类具有所有像素推送逻辑,但没有内部状态。实际上,GraphicPrimitive层次结构表示Command Objects的层次结构。

在GeometryPrimitive基类中,包含一个名为GetGraphicPrimitive()的抽象方法。在GraphicPrimitive基类中,包含一个称为Draw(Graphics g)的抽象方法。

在每个GeometryPrimitive中,包括用于绘制对象的适当的GraphicPrimitive和用于访问该对象的访问器方法。要绘制整个场景,请遍历GeometryPrimitive对象的结构,向每个对象要求其GraphicPrimitive,然后调用Draw()方法。

abstract class GeometryPrimitive
{
    public abstract GraphicsPrimitive GetGraphicsPrimitive();
}

abstract class GraphicsPrimitive
{
    public abstract void Draw(Graphics g);
}

class RectangleGeometryPrimitive : GeometryPrimitive
{
    public Point TopLeft {get; set;}
    public Point BottomRight {get; set;}

    private RectangleGraphicPrimitive gp;

    public RectanglePrimitive(Point topLeft, Point bottomRight);
    {
        this.TopLeft = topLeft;
        this.BottomRight = bottomRight;
        this.gp = new RectangleGraphicsPrimitive(this);
    }

    public GraphicsPrimitive GetGraphicsPrimitive()
    {
        return gp;
    }
}

class RectangleGraphicsPrimitive : GraphicsPrimitive
{
    private RectangleGeometryPrimitive p;

    public RectangleGraphicsPrimitive(RectangleGeometryPrimitive p)
    {
        this.p = p;
    }

    public void Draw(Graphics g)
    {
        g.DrawRectangle(p.TopLeft, p.BottomRight);
    }
}

class CircleGeometryPrimitive : GeometryPrimitive
{
    public Point Center {get; set;}
    public int Radius {get; set;}

    private CircleGraphicPrimitive gp;

    public RectanglePrimitive(Point center, int radius);
    {
        this.Center = center;
        this.Radius = radius;
        this.gp = new CircleGraphicsPrimitive(this);
    }

    public GraphicsPrimitive GetGraphicsPrimitive()
    {
        return gp;
    }
}

class CircleGraphicsPrimitive : GraphicsPrimitive
{
    private CircleGeometryPrimitive p;

    public CircleGraphicsPrimitive(CircleGeometryPrimitive p)
    {
        this.p = p;
    }

    public void Draw(Graphics g)
    {
        g.DrawCircle(p.Center, p.Radius);
    }
}

如您在上面看到的,不需要向下转换就可以将GeometryPrimitives绘制到屏幕上。通过正确使用继承,您还可以在不同的GeometryPrimitive之间共享GraphicsPrimitive对象。例如,如果SquareGeometryPrimitive从RectangleGeometryPrimitive派生,则SquareGeometryPrimitive和RectangleGeometryPrimitive都可以​​使用RectangleGraphicsPrimitive。

关于oop - 在类(class)等级制度中经常下垂是永远邪恶的吗?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/1485950/

10-14 15:44