2010-06-22 59 views
1

我做了一个例子。代表其他对象的对象集合的面向对象设计

我有一类这个类的

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

回答

1

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

这种方法的诸多优点之一是,您可以在不更改基础人员表示的情况下更改视图表示。如果您还有一天需要两个PersonView(例如因为您需要在两个屏幕上绘制一个人),则可以为每个屏幕创建一个PersonView。如果(例如)你将屏幕位置硬连线到Person类中,这是不可能的。

+0

是的,我今天想知道它,现在正在实施它。我决定有例如。 'Vertex'对象和子类:'DrawableVertex'带有附加字段。该视图将得到'DrawableGraph'。我正在使用C#,所以我决定有'Graph 其中T:Vertex'和'DrawableGraph:Graph '(我忽略了边)。我不知道这是不是个好主意,但现在代码看起来更清晰。 – prostynick 2010-06-23 17:17:12

0

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

class Person 
{ 
    class Properties 
    { 
    Point location; 
    } 

    Properties properties; 
} 

画家可能不应该子类化它的绘画;相反,我想你想:

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

我觉得你最好的选择是有一个人知道自己的位置。例如:

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

这取决于你怎么看你的人,这是什么实体代表您的域名,如果它是绘制对象 - 不是把点内,忘掉它,但是如果你的人是与绘图无关的东西,所以你的绘图子系统知道关于Person的一些东西,而且域对绘图一无所知,比你需要另一个实体,像DrawablePerson(可能不是一个很好的名字),它将封装所需的所有数据可以这样初始化:

Person person = //comes from somewhere 

DrawablePerson drawablePerson = new DrawablePerson(person); 

所以它取决于你的型号。

0

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

但如果我这样做,将PersonProperties的新对象,这一名单时,我必须非常小心,因为我可以用里面的相同Person实例的两个对象结束。

不特别 - 在开始时为模型中的所有人员创建渲染,并在人物添加到模型时创建渲染,并在人物从模型中移除时移除渲染。没有其他要求。