tags:

views:

106

answers:

5

I made up an example.

I have a class

class Person
{
    //stuff
}

Objects of this class are used here and there etc. But I will like to make separate class, that will be responsible for drawing persons. So I will need eg. a location of Person object on the screen.

I could inherit from Person:

class PersonVis : Person
{
    Point location;
}

But I am not sure that PersonVis should have "is a" relation with Person.

I could make a dictionary with Person as key and PersonProperties as value:

class PersonProperties
{
    Point location;
}

But I could have a situation, where one of property of PersonProperties class depends on state of Person, so maybe instead of using dictionary, I should use just a list of:

class PersonProperties
{
    Person person;
    Point location;
}

But if I do that I must be very careful when inserting new object of PersonProperties to that list, because I could end up with two objects with the same Person instance inside.

In your opinion, what is the best choice?

EDIT

I think I have to come out with real example.

I have class Graph

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

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

I am using this class to solve problems. I don't need graphic representation at all and I don't need for example location of the vertex.

Now I created class for drawing this graph:

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

Vertices can be eg. moved, so properties of drawing changes and graph must be redraw.

XXX is the structure that holds information about eg. current points of vertices.

I don't know what kind of XXX I should choose.

XXX could be: Dictionary<Vertex, VertexProperties> where VertexProperties:

class VertexProperties
{
    Point location;
}

But I could have a situation, where one of property of VertexProperties class depends on state of Vertex. So maybe List<VertexProperties> where VertexProperties:

class VertexProperties
{
    Vertex vertex;
    Point location;
}

But if I do that I must be very careful when inserting new object of VertexProperties to that list, because I could end up with two objects with the same Vertex instance inside.

And maybe List<VertexVis> where VertexVis:

class VertexVis : Vertex
{
    Point location;
}

But this is the same as in previous + I don't feel that VertexVis "is a" Vertex.

A: 

I don't know what the difference is between Person and PersonProperties; perhaps you can say:

class Person
{
  class Properties
  {
    Point location;
  }

  Properties properties;
}

The painter probably shouldn't subclass what it's painting; instead I guess you want:

class Screen
{
  void paint(Person person) {...}
}
ChrisW
A: 

I think your best option is to have a Person know his own location. For example:

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

It depends on how are you looking on your person, what this entity represents in your domain, if it is an object for drawing - than put Point inside and forget about it, but if your person is something that has nothing to do with drawing, so your drawing subsystem knows somehting about Person and domain knows nothing about drawing, than you need another entity, something like DrawablePerson (maybe not a very good name), that will incapsulate all data needed for drawing and can be initialized like this:

Person person = //comes from somewhere

DrawablePerson drawablePerson = new DrawablePerson(person);

So it depends on your model.

Restuta
A: 

I've always used the version where the object with the rendering properties has a reference to the data, and if necessary it also has a listener for changes to the model. I've never needed to optimise mapping from a person to its rendering - usually the slow operations have been rendering data, and if you need a fast response to changing the presentation to changing the model then listeners handle that - just amalgamate redraw events rather than redrawing on every change.

But if I do that I must be very careful when inserting new object of PersonProperties to that list, because I could end up with two objects with the same Person instance inside.

Not especially - create renderings for all persons in the model at the start, and create a rendering when a person is added to the model, and remove the rendering if the person is removed from the model. Nothing else is required.

Pete Kirkham
+1  A: 

You are probably looking for Model-View-Controller or something similar. This separates out the object (Person) from its representation (PersonView, which would be another class). I'll let you research this more yourself, since there are too many good sites to choose from. Normally PersonView (the View) contains a reference to Person (the Model).

Among the many advantages of this approach are that you can change the View representation without changing the underlying Person representation. If you also one day needed two PersonViews (for example because you needed to draw a person on two screens) you can just create one PersonView for each screen. This would not be possible if (for example) you hardwired the screen location into Person class.

DJClayworth
Yeah, I was wondering about it today and I am implementing it right now. I've decided to have eg. `Vertex` object and subclass: `DrawableVertex` with additional fields. The view will get `DrawableGraph`. I am using C#, so I've decided to have `Graph<T> where T : Vertex`, and `DrawableGraph : Graph<DrawableVertex>` (I omitted edges). I don't know if it is good idea, but the code looks much clearer now.
prostynick