首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

工廠模式陷阱:雙向引用導致的循環依賴如何破解?

     編輯:程式設計綜合問答

問題現場:Person ↔ Computer 死結

class Person { Computer myComputer; }
class Computer { Person myOwner; }

當嘗試用工廠創建「小明」並賦予「HP 電腦」時,工廠陷入無限遞歸:創建 Person → 需 Computer → 需 Person → …

核心原因分析

  1. 構造函數注入強制雙向綁定:雙方在構造期就要求對方實例已存在,邏輯上無解。
  2. 領域模型不合理:現實中「人出生時不抱電腦」「電腦出廠時無主人」,強行在構造期建立關係違背業務常識。
  3. 工廠職責過重:工廠試圖一次性構建整張對象圖,而非分階段組裝。

三種破解方案

方案一:延遲關聯(Setter/屬性注入)

// 工廠只負責創建單個對象
Person p = personFactory.create("小明");
Computer c = computerFactory.create("HP");
// 由上層協調者(或 Builder)建立關聯
p.setComputer(c);
c.setOwner(p);

✅ 符合現實邏輯 ✅ 解除構造期循環 ⚠️ 需確保調用方正確設置

方案二:弱引用/單向依賴

若 Computer 不需主動持有 Owner 引用,改為 WeakReference<Person> 或移除該字段,僅保留 Person → Computer 單向關聯。單向依賴天然無循環。

方案三:引入中介者/聚合根

class OwnershipService {
  void assign(Person p, Computer c) { ... } // 管理關聯、持久化、事件發布
}

將雙向關聯提升為領域服務,工廠只創建獨立實體,關聯由服務層管理。

最佳實踐原則

  • 構造函數只注入「不可變的核心依賴」,可選關聯用 Setter。
  • 識別聚合根,由聚合根工廠創建整個聚合,內部實體不直接互相引用。
  • 考慮事件驅動:PersonCreated 事件觸發 Computer 綁定,解耦創建時序。

總結

循環依賴本質是領域建模與對象創建策略不匹配。優先調整模型(單向/弱引用/中介者),再配合 Builder 或分階段工廠組裝,即可優雅化解。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved