代码之家  ›  专栏  ›  技术社区  ›  prostynick

面向对象的对象集合设计

oop
  •  1
  • prostynick  · 技术社区  · 16 年前

    我举了个例子。

    我有一节课

    class Person
    {
        //stuff
    }
    

    这个类的对象在这里和那里使用,等等。但是我想创建一个单独的类,负责绘制人员。所以我需要一个 Person 屏幕上的对象。

    我可以继承 :

    class PersonVis : Person
    {
        Point location;
    }
    

    但我不确定 PersonVis 应该与…有“is a”关系 .

    我可以用 作为关键和 PersonProperties 作为价值:

    class PersonProperties
    {
        Point location;
    }
    

    但我可以有一种情况 个人财产 类取决于的状态 因此,也许我不使用字典,而应该使用以下列表:

    class PersonProperties
    {
        Person person;
        Point location;
    }
    

    但是如果我这样做,在插入 个人财产 因为我可以得到两个相同的物体 实例在内部。

    在你看来,最好的选择是什么?

    编辑

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

    我有课 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可能是: Dictionary<Vertex, VertexProperties> 在哪里? VertexProperties :

    class VertexProperties
    {
        Point location;
    }
    

    但我可以有一种情况 顶点属性 类取决于的状态 Vertex . 所以也许 List<VertexProperties> 在哪里? 顶点属性 :

    class VertexProperties
    {
        Vertex vertex;
        Point location;
    }
    

    但是如果我这样做,在插入 顶点属性 因为我可以得到两个相同的物体 顶点 实例在内部。

    也许 List<VertexVis> 在哪里? VertexVis :

    class VertexVis : Vertex
    {
        Point location;
    }
    

    但这和以前的一样+我不觉得 顶点 “是” 顶点 .

    5 回复  |  直到 16 年前
        1
  •  1
  •   DJClayworth    16 年前

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

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

        2
  •  0
  •   ChrisW    16 年前

    我不知道人与人之间的区别是什么,也许你可以说:

    class Person
    {
      class Properties
      {
        Point location;
      }
    
      Properties properties;
    }
    

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

    class Screen
    {
      void paint(Person person) {...}
    }
    
        3
  •  0
  •   Jacob    16 年前

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

    class Person {
       string name;
       Point location;
       //any other fields...
     }
    
        4
  •  0
  •   Restuta    16 年前

    这取决于你如何看待你的人,这个实体在你的领域中代表了什么,如果它是一个绘画的对象-比把点放在里面然后忘记它,但是如果你的人与绘画无关,所以你的绘画子系统知道一些关于人的事情,而领域对绘画一无所知,比你需要的另一个实体,类似drawableperson(可能不是一个很好的名称),它将封装绘图所需的所有数据,并可以这样初始化:

    Person person = //comes from somewhere
    
    DrawablePerson drawablePerson = new DrawablePerson(person);
    

    所以这取决于你的模型。

        5
  •  0
  •   Pete Kirkham    16 年前

    我一直使用这个版本,在这个版本中,具有渲染属性的对象引用了数据,并且如果需要,它也有一个侦听器来侦听模型的更改。我从来没有必要优化从一个人到其呈现的映射-通常缓慢的操作一直在呈现数据,如果您需要对将演示更改为更改模型的快速响应,监听器就会处理这一点-只是合并重绘事件,而不是重绘每个更改。

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

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