面向对象的对象集合设计,代表其他对象

时间:2010-06-22 20:10:56

标签: oop

我做了一个例子。

我有一个班级

class Person
{
    //stuff
}

此类的对象在这里和那里等使用。但我想制作单独的课程,负责绘制人员。所以我需要例如。屏幕上Person对象的位置。

我可以继承Person

class PersonVis : Person
{
    Point location;
}

但我不确定PersonVis应该“是与Person的关系。”

我可以制作一个字典,其中Person为关键字,PersonProperties为值:

class PersonProperties
{
    Point location;
}

但是我可能会遇到这样的情况:PersonProperties类的属性之一取决于Person的状态,所以也许不使用字典,我应该只使用以下列表:

class PersonProperties
{
    Person person;
    Point location;
}

但是,如果我这样做,我必须非常小心地将PersonProperties的新对象插入到该列表中,因为我最终会得到两个内部具有相同Person实例的对象。

在您看来,最佳选择是什么?

修改

我想我必须提出真实的例子。

我上课Graph

class Graph
{
    List<Vertex> Vertices;
    //other stuff
}

class Vertex
{
    //stuff not related to drawing at all
}

我正在使用这个类来解决问题。我根本不需要图形表示,我不需要顶点的示例位置。

现在我创建了用于绘制此图形的类:

class GraphDrawer
{
    Graph GraphToDraw;

    XXX xxx;

    void OnDraw()
    {
        //use vertices from graph, but use also stored positions of the vertices
        //and any other things related to drawing
    }
}

顶点可以是例如。移动,因此必须重绘绘图更改和图形的属性。

XXX是保存有关例如的信息的结构。当前的顶点。

我不知道应该选择什么样的XXX。

XXX可以是:Dictionary<Vertex, VertexProperties>其中VertexProperties

class VertexProperties
{
    Point location;
}

但我可能会遇到这样的情况:VertexProperties类的属性之一取决于Vertex的状态。所以也许List<VertexProperties> VertexProperties

class VertexProperties
{
    Vertex vertex;
    Point location;
}

但是如果我这样做,我必须非常小心地将VertexProperties的新对象插入到该列表中,因为我最终可能会有两个内部具有相同Vertex实例的对象。

也许List<VertexVis> VertexVis

class VertexVis : Vertex
{
    Point location;
}

但这与之前的相同+我不认为VertexVis“是”Vertex

5 个答案:

答案 0 :(得分:1)

您可能正在寻找Model-View-Controller或类似的东西。这将对象(Person)与其表示(PersonView,它将是另一个类)分开。我会让你自己研究一下,因为有太多好的网站可供选择。通常PersonView(视图)包含对Person(模型)的引用。

此方法的众多优点之一是您可以在不更改基础Person表示的情况下更改View表示。如果您有一天还需要两个PersonView(例如,因为您需要在两个屏幕上绘制一个人),您可以为每个屏幕创建一个PersonView。如果(例如)您将屏幕位置硬连线到Person类,则无法进行此操作。

答案 1 :(得分:0)

我不知道Person和PersonProperties之间有什么区别;也许你可以说:

class Person
{
  class Properties
  {
    Point location;
  }

  Properties properties;
}

画家可能不应该将其绘画的内容细分;相反,我想你想要:

class Screen
{
  void paint(Person person) {...}
}

答案 2 :(得分:0)

我认为你最好的选择是让一个人知道他自己的位置。例如:

class Person {
   string name;
   Point location;
   //any other fields...
 }

答案 3 :(得分:0)

这取决于你如何看待你的人,这个实体在你的领域中代表什么,如果它是一个绘图的对象 - 而不是把Point放在里面而忘记它,但如果你的人是无关的东西有了绘图,所以你的绘图子系统知道有关人物和领域一无所知的绘图,而不是你需要另一个实体,比如DrawablePerson(可能不是一个很好的名字),它将填充绘图所需的所有数据,并且可以像这样初始化:

Person person = //comes from somewhere

DrawablePerson drawablePerson = new DrawablePerson(person);

所以这取决于你的模特。

答案 4 :(得分:0)

我一直使用具有渲染属性的对象具有对数据的引用的版本,并且如果需要,它还具有用于更改模型的侦听器。我从来没有需要优化从人到渲染的映射 - 通常慢速操作已经渲染数据,如果你需要快速响应改变演示文稿以改变模型,那么听众处理它 - 只是合并重绘事件而不是重新绘制每一个变化。

  

但是如果我这样做,我必须非常小心地将PersonProperties的新对象插入到该列表中,因为我最终可能会有两个具有相同Person实例的对象。

不是特别 - 在开始时为模型中的所有人创建渲染,并在将人添加到模型时创建渲染,如果从模型中删除了人,则删除渲染。不需要其他任何东西。