2010-04-11 132 views
7

當我爲自己的項目構建自己的系統時,我正在學習很多關於設計模式的知識。我想問你一個我無法找到答案的設計問題。兩個互相依賴的對象。那不好嗎?

目前我正在使用帶有多個客戶端的套接字構建一個小型的聊天服務器。現在,我有三大類:

  1. 人級持有像尼克,年齡和房間對象的信息。
  2. 房間級別其中包含房間名稱,主題和當前在該房間中的人員列表等信息。
  3. Hotel-class其中包含服務器上的人員列表和客房列表。

我已經做了示意圖來說明吧:

我在酒店級服務器上的人員名單,因爲這將是很好的跟蹤有多少人在線現在(不必遍歷所有房間)。 因爲我希望能夠在不搜索房間的情況下搜索特定人員,所以住在酒店級別的人。

這是不好的設計?有沒有另外一種方法來實現它?

謝謝。

回答

4

的類之間的相互依存問題,嚴格來說,可以通過使用接口(抽象類,如果您的語言是例如C++或Python)IRoomIPerson來解決;在僞

interface IPerson 
    IRoom getRoom() 
    // etc 

interface IRoom 
    iter<IPerson> iterPerson() 
    // etc 

這使得只有接口互相依賴對方 - 實際實現的接口只需要取決於接口。

如果你想避免循環參考迴路(這可能是一個麻煩,例如,在CPython中通過減慢垃圾回收) - 你可以使用弱引用,具有典型「一對多關係」表等的底層關係數據庫等等。對於第一個簡單的原型,你可以使用你選擇的語言中最簡單的原型(可能是簡單的,並且必然是循環的,參考[C++中的指針]],參考RoomRoomlist<Person>Person

+1

我看到「相互依存」是我正在尋找的詞。爲了記錄我正在用Java寫這個。界面方法看起來很有趣,但並沒有使解決方案變得更加不同,但我明白你的觀點。感謝您的評論。 – 2010-04-11 03:10:29

+2

@Kasper,關鍵是,依賴於_interfaces_(包括相互之間)沒有真正的問題 - 它主要依賴於您想要避免的_concrete_軟件(例如,在「循環」的情況下)。自由開始一個快速而骯髒的實現並在稍後轉向更加健全的實現,這也加快了軟件原型設計和迭代的演變和維護。 – 2010-04-11 03:27:40

9

我不喜歡它。酒店包含客房,而客房則包含人。人們不包含房間,他們屬於他們。

您不一定非得重複才能讓您的客人數。您可以保留一個運行計數($ Hotel-> total_guests),並在更改時對其進行修改。

+0

我明白你的意思,我的邏輯存在缺陷,謝謝指出!然而,我的想法是,包含用戶名和Person對象的HashMap在搜索用戶方面比在迭代Rooms更快。 – 2010-04-11 02:57:30

+4

我完全讚賞你的慾望毫秒,因爲我分享激情 - 但令人敬畏的OOP是關於更快/更乾淨的閱讀和編寫代碼,而不是更快的執行時間。我建議你在兩種方式和時間上嘗試 - 差異可能不會像你想象的那麼大。 (如果你這樣做,請發佈你的結果給我們!) – 2010-04-11 03:07:29

+0

你讓我!關於慾望毫秒的評論很有用。你給了我一些想法,謝謝:) – 2010-04-11 03:17:18

1

在一個更大的系統中,這將會很糟糕,但是從我瞭解您的應用程序的情況來看,這三個類只能一起使用,這不算什麼問題。只要確保以表明它包含對房間的引用而不是實例的方式來命名該人的成員變量。另外,除非出於性能方面的原因(例如,你將擁有大量的房間),否則可能會更清潔地製作一個將迭代房間並收集人員的屬性或吸氣器,而不是緩存它們酒店。

+0

爲了記錄,我同意將它們緩存爲酒店的財產可能不是最好的方式去解決它。我個人也會迭代;) – 2010-04-11 02:53:27

+0

你會如何命名Person中的成員變量,所以它會更像是一個引用? 假設我有大量的用戶,而且我需要搜索單個用戶。什麼是最好的方法?我知道我在參考文獻中保留了冗餘信息。這些類只能一起使用(還有幾個,但不是很多)。 – 2010-04-11 03:03:54

0

相互依賴本身並不壞。有時數據使用需要它。

我以不同的方式思考它。維護一般具有較少關係的代碼會更容易 - 相互依賴與否。儘量保持簡單。在你創建和刪除序列的過程中,你的情況唯一的額外技巧是有時會出現檢查和蛋問題。你有更多的鏈接來保存圖書。

如果您在詢問這種情況下是否需要酒店的人員列表,我認爲有兩個答案。我會首先讓您的對象(在內存中)提供這些關係,但是您不需要數據庫中人員和酒店之間的額外連接表。如果你使用的是Hibernate,如果你問它爲酒店的人(它會加入hotels.hotel_id上的酒店),它會自動生成一個有效的加入。