2010-06-22 72 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實例的兩個對象結束。

不特別 - 在開始時爲模型中的所有人員創建渲染,並在人物添加到模型時創建渲染,並在人物從模型中移除時移除渲染。沒有其他要求。