[英]Is the practice of passing parent object as reference for parent object interaction Evil?
在最近我一直在做的遺留c#代碼的一些代碼評論中,我見過很多像這樣的例子:
class ManagerParentClass
{
public string CustomProperty{get;set;}
public void Log(string message);
void DoABunchOfTasks()
{
new SomethingService().DoSomething(this);
}
}
以下內容:
public class SomethingService
{
ManagerParentClass _manager;
void DoSomething(ManagerParentClass manager)
{
_manager = manager;
// do something
_manager.CustomProperty = "hello world";
_manager.Log("said hello world");
}
}
雖然這在表面上運行良好,但我擔心這是一種反模式,可能會導致垃圾收集的邪惡事物。
這會破壞.Net能否正確清理父對象和子對象的能力或其他任何負面影響的世代垃圾收集器?
哦,是的,這是一個可怕的反模式。 我使用的代碼庫使用了很多,而且非常瘋狂。
最大的進攻? 違反封裝以及它附帶的類之間的緊密耦合: SomethingService
對ManagerParentClass
了解太多,而ManagerParentClass
放棄了對SomethingService
控制。
兩個更好的選擇:
DoSomething()
成為ManagerParentClass
的實例方法,這與面向對象的基本點保持一致:數據結構帶有運算符 SomethingService
成為一個純方法,進行一些計算並返回一個值,然后調用者可以對ManagerParentClass
進行賦值 當然,這兩個重構都涉及到ManagerParentClass
的最終游戲變異,並且來自函數式編程角度,我會盡量避免這種情況。 但是如果沒有更多信息,我不能為此推薦一門課程。
這實際上是一種將類相互分離的好方法 - 你所寫的內容看起來很像訪問者模式。
您編寫的示例根本沒有太大的內存影響,因為除了該方法的長度之外,SomethingService不會保留在ManagerParentClass上。 如果我們假設SomethingService會在構造或常規方法中保存這樣的實例,那么它會稍微復雜一些。
讓SomethingService持有對ManagerParentClass的引用意味着ManagerParentClass將保留在引用1)中,只要SomethingService通過引導回GC根的某些引用鏈保存在內存中,並且2)只要SomethingService保持其引用MPC。
如果SS要釋放它的引用(將其清空),那么問題就解決了。 如果SS本身不再被任何東西引用,那么GC將知道SS可以是GCd,並且如果MPC然后僅由SS保持,那么MPC可以依次是GCd。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.