為什麼不建議乙個物件在多處儲存引用?

時間 2021-05-31 01:03:53

1樓:

既然每個item都存有area, 那麼乙個item只能對應乙個area. (包括 null area), 是從屬關係.

那麼最"優雅"的做法應該是直接讓 itemManager 變成對所有 area 下的 itemList 的封裝, 內部用迭代器或索引去轉換.

2樓:dwing

"不建議乙個物件在多處儲存引用"的出發點是對的, 多處引用容易出現不一致和記憶體洩漏問題.

但凡事不能絕對, 像題目中所說的具體問題就得考慮效能是否更加重要, 必要的時候就應該犧牲單引用的原則.

如果所有問題都能單引用解決, 那記憶體管理早就不是棘手問題了, 甚至連GC都不需要了, 但現實需求總是很複雜的, 該用多引用的地方就去用好了, 不一致和記憶體洩漏也有其它手段來解決. 但反過來不用多引用恐怕沒有辦法解決效能問題.

另外有的回答用了索引的方法, 其實也可以看成是一種引用, 也有維護和一致性的問題, 甚至有時比直接引用更危險.

3樓:

你跟盧森堡老哥之間是不是有某種對立

這個問題,你看一下關係型資料庫是怎麼解決這個問題的嘛,看懂了解決方案再抄乙份就好了

盧森堡老哥愛怎麼想就怎麼想,管咱屁事。

我感覺你就是不爽盧森堡老哥

4樓:熊傑

盧森堡的觀點,方向上是正確的。同乙個東西。 最好不要在多處儲存。在不考慮效能的情況下。 從源頭去取當然是最好的, 最準確的。

要考慮效能的情況。 比如你說的area 自己存乙個 list。 可以考慮變成存乙個 list。

itemId 指向了原始資料 item。 而且一指取引用操作在效能是幾乎是忽略不計的。 在記憶體上也避免了儲存多份 item 的開銷。

還有另一種解決效能的方法是快取。 舉個例子。 乙個正文形有長l, 寬w兩個變數。

但是在程式中可能會頻繁的取面積。一種做法是每次修改l,w都改面積。 另一種做法是在取面積的時候使用 l * w。

然後可以使用快取(l,w不變的情況下直接返回上次計算的結果)來解決效能問題。

5樓:facetothefate

area 裡存item

item裡存area 這都是不對的

item可以屬於多個area

area可以屬於多個item

顯然他們兩個之間是多對多的關係

如果這裡是資料庫建模,多對多是怎麼實現的呢?我們會建乙個新表來儲存area 和item的關係。

這個技巧是通用的。實際上你需要的是乙個專門負責儲存area 和item 關係的類。

這樣你所有的area 和 item都不存在互相引用的問題,無需擔心維護乙個list

通過這個class可以對雙方關係進行集中式的管理。

所有關於area item關係發生變化都只需要通知該類即可

渲染也無需遍歷所有的item 而是可以直接通過area 來找到所有關於area 的item

解決不了問題的時候,往往引入中間層就可以了……

6樓:79nos

可以考慮不暴露Area內部的儲存Item的容器,而是給Area增加AddItem和RemoveItem方法,由它們新增到內部的容器中,同時修改Item的Area欄位(而且只在這裡)。

如果你選用的程式語言沒有友元的概念話,那就只能靠口頭約定來避免在其他地方對Area欄位進行修改。

7樓:

一般不會像你說的出現判斷,Item.area.isCurrentArea的情況,查詢都是條件查詢,判斷是否是當前需要的資料,說明你查詢的時候引數就不對。

你只有引數對了,介面才能返回正確的資料給你。

出現的這樣的情況,唯一的可能就是你引數不對。

但是你說的針對不同的頁面,返回不同的list是通常的做法,特別是移動端,移動端是不喜歡出現null的,你要對資料做非空判斷,保險一點就是只給移動端想要的資料,也就是說針對不同的area,給出不同的的list然後對每個資料都做非空判斷。

如果你後端非空判斷做的好,你可以返回整個list。即使你資料庫層面做了非空判斷,你還是有很多問題。

返回list絕對可以更好的減少bug。

8樓:

他建議只儲存在ItemMgr中,然後如果要渲染某個Area那就遍歷一遍ItemMgr然後判斷Item.area.isCurrentArea 然後進行渲染,可是這樣做了很多多餘的操作,我感覺很不值得

如果效能分析的結論是會帶來效能問題,那就用冗餘。如果不會,那冗餘並不一定是好選擇。

9樓:Ivony

這個問題簡單多了。

不論是Area裡面有乙個儲存Item容器,還是Item上面有乙個Area引用,都已經有足夠的資訊。所以現在的問題是在於,當Item上已經有Area的引用的時候,那麼Area是否還有必要保留對Item的引用。

這是個典型的關於冗餘的問題。

冗餘會帶來什麼問題?

首先是占用更多的儲存空間,但這通常不成為乙個問題,尤其是只儲存乙個引用的時候。

那麼另外乙個問題就是資料一致性的問題,當冗餘資料出現,就可能存在資料的不一致。在這個例子裡面,譬如說a : Area儲存了b : Item的引用,但是b的Area屬性不是a。

這就是資料不一致,這時候我們不知道b到底是屬於a還是不屬於。或者說通過不同的方式處理資料的時候,例如我們遍歷a的時候能找到b,但是找b的容器的時候又找不到a。

為了避免出現一致性的問題,我們通常需要做原子性操作,原子性就是說多個操作要麼都成功,要麼都失敗。例如我們讓a新增子元素b和設定b的Area屬性為a這兩個操作是原子性的,要麼都成功要麼都失敗,就可以避免產生資料不一致的問題。

但遺憾的是,原子性是非常難做到的一件事情,很多時候代價非常大。因為我們要處理非常多的異常情況,例如操作被中斷,資料寫入時出現故障,併發衝突等等。

當然,大多數時候我們只要把兩個操作寫在乙個方法裡面或者其他強約束就足夠滿足了。更長的生命週期,更重要的資料會有更加嚴苛的要求。

但是即便做不到絕對的原子性,我們也不一定就會出現資料不一致的情況。而即便出現了資料不一致的情況,也不一定就無法進行修復和補救,例如我們可以強行認定Area屬性是正確的資料,據此來修復所有的不一致情況。

所以,這只是乙個需要權衡的問題。冗餘會帶來更好的效能,但是也會帶來資料不一致的風險。

10樓:張澤陽

n個area,n個item

item manager作為list儲存items,而你現在的意圖是給area新增乙個list屬性.,那麼可能是怕深拷貝和淺拷貝帶來的資料一致性不好維護還有就是變更item所屬area操作更加麻煩list由原來的1個增加為n+1

犧牲了演算法的空間複雜性

取決於實際操作需求,演算法的時間複雜性不一定佔優

為什麼很多不優秀不漂亮的女孩,反而物件乙個接乙個?

Ziyan Zeng 千萬不要小看看起來不優秀不起眼的女生 集郵的都是她們,只要樣子不是太難看,打扮不是太懶,自信愛笑活潑的女生,能隨隨便便泡完整個理工學院好嗎?大多時候,活潑性格還真能為相貌拉不少分,君不見能和一幫男生打成一片稱兄道弟的女生,都不會是那種女神麼? 你可能不知道,這世界上還有很多宅男...

為什麼python中不建議在for迴圈中修改列表?

扁平結構比巢狀結構更好 Python之禪 比如 list map lambda x 4 if x 3 else x,a 如果一定要用for a 1,2,3,4,5,6 3變成4 4 if x 3 else x for x in a b 1,2,4,4,5,6 x for x in b if x 4 ...

為什麼我的手機儲存明明夠卻一直顯示儲存不足。(手機型號OPPO A33)?

淺笑心柔 我出問題的手機,也是這個型號,而且問題也一樣,估計很可能是這更新的系統版本不相容,我這手機買了四五年了,早給我老子玩遊戲當遊戲機了。我這次回家他說手機不知道怎麼回事出了點問題,讓我看看,恢復出廠也沒用,乙個軟體不執行,儲存空間足夠還是提示。 瑠衣 已經有老哥說過這玩意已經是古董了。所以就這...