設計模式-迪米特法則(Law of Demeter, LoD)


迪米特法則(Law of Demeter, LoD)

別名:最少知識原則(Least Knowledge Principle)
核心思想:一個對象應盡可能少地與其他對象發生交互,只與直接的朋友(成員變量、方法參數、方法返回值中的對象)通信,避免依賴間接的類。


原理詳解

  1. 直接朋友的定義

    • 當前對象的成員變量。
    • 當前對象方法的參數。
    • 當前對象方法的返回值。
    • 當前對象方法中創建的對象(不推薦,但允許)。
  2. 禁止鏈式調用
    避免出現 a.getB().getC().doSomething() 的調用形式,這種“火車殘骸式”代碼會增加耦合性。

  3. 目標

    • 降低耦合:減少模塊間的依賴,提升代碼可維護性。
    • 提高封裝性:隱藏內部實現細節,僅暴露必要接口。

應用案例

場景1:訂單系統獲取用戶配送地址
錯誤設計(違反迪米特法則)
public class User {private Order order;public Order getOrder() { return order; }
}public class Order {private Address shippingAddress;public Address getShippingAddress() { return shippingAddress; }
}public class Address {private String city;public String getCity() { return city; }
}// 客戶端代碼:鏈式調用(直接訪問深層對象)
User user = new User();
String city = user.getOrder().getShippingAddress().getCity();

問題

  • 客戶端需要了解 UserOrderAddress 的內部結構。
  • 修改 OrderAddress 的結構會影響客戶端代碼。
正確設計(遵循迪米特法則)
public class User {private Order order;public String getShippingCity() {return order.getShippingCity(); // 委托給 Order 類}
}public class Order {private Address shippingAddress;public String getShippingCity() {return shippingAddress.getCity(); // 委托給 Address 類}
}public class Address {private String city;public String getCity() { return city; }
}// 客戶端代碼:僅與直接朋友交互
User user = new User();
String city = user.getShippingCity();

優勢

  • 客戶端只需與 User 交互,無需了解 OrderAddress 的細節。
  • 修改 OrderAddress 的結構不會影響客戶端代碼。

場景2:文件系統目錄結構遍歷
錯誤設計(違反迪米特法則)
public class Directory {private List<File> files;private List<Directory> subDirectories;public List<File> getFiles() { return files; }public List<Directory> getSubDirectories() { return subDirectories; }
}// 客戶端代碼:直接遍歷深層結構
public void printAllFiles(Directory root) {for (File file : root.getFiles()) {System.out.println(file.getName());}for (Directory subDir : root.getSubDirectories()) {printAllFiles(subDir); // 遞歸調用暴露內部結構}
}

問題

  • 客戶端需要了解目錄的遞歸結構,耦合度高。
正確設計(遵循迪米特法則)
public class Directory {private List<File> files;private List<Directory> subDirectories;// 封裝遍歷邏輯,客戶端無需了解內部結構public void traverseFiles(Consumer<File> fileConsumer) {files.forEach(fileConsumer);subDirectories.forEach(subDir -> subDir.traverseFiles(fileConsumer));}
}// 客戶端代碼:僅調用高層方法
Directory root = new Directory();
root.traverseFiles(file -> System.out.println(file.getName()));

優勢

  • 客戶端僅依賴 DirectorytraverseFiles 方法,不關心內部實現。
  • 目錄結構的遍歷邏輯被封裝,修改不影響客戶端。

迪米特法則的實踐意義

  1. 減少耦合:模塊間通過接口通信,而非直接操作內部對象。
  2. 提升可維護性:修改一個類的內部結構時,無需調整其他模塊。
  3. 增強可測試性:依賴越少,單元測試越容易隔離和模擬。

常見違反場景及修復

違反場景修復方法
鏈式調用(a.getB().getC()封裝中間調用,提供高層接口(如 a.getC()
暴露集合內部結構返回不可變集合或迭代器,避免直接操作
方法參數傳遞復雜對象拆分參數為基本類型或接口

總結

迪米特法則通過限制對象間的交互范圍,推動代碼向高內聚、低耦合的方向演進。其核心是封裝委托,適用于任何需要降低依賴關系的場景,尤其在大型系統或模塊化架構中價值顯著。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/85309.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/85309.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/85309.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

python獲取AB直線間任意一點經緯度

獲取AB直線間任意一點經緯度 1、目標 已知A點經緯度,距離;B點經緯度,距離,如果C點在AB之間,且知道C點距離,求C點的經緯度信息。 目標:在AB這條直線上,根據給定的距離(從A點開始沿直線到某點的距離)來求該點的經緯度。 2、方法 首先計算AB的總長度(大圓距離),…

Android實戰——系統字體庫加載流程

Android 系統字體庫指的是在Android設備上用于顯示文本的字體集合。隨著Android系統的更新,其對字體的支持也日益增強,允許開發者和用戶更靈活地定制界面文字顯示。 一、字體庫介紹 1、字體庫文件 字體庫文件是指存儲字體數據的文件,這些文件包含了創建文本字符所需的所有…

嵌入式樂鑫音頻項目“無聲”問題深度調試復盤與方法論總結

前言&#xff1a;一場典型的“工程師尋蹤之旅” 本次調試始于一個看似簡單卻極其頑固的問題&#xff1a;在一個基于樂鑫ESP-ADF&#xff08;音頻開發框架&#xff09;的DuerOS示例項目中&#xff0c;移植到M5Stack ATOMIC Echo Base硬件上后&#xff0c;程序能夠成功編譯、燒錄…

地下安全防線:電纜通道防外破地釘如何守護城市隱形生命線

在繁華都市的柏油馬路之下、在靜謐鄉村的泥土深處&#xff0c;縱橫交錯的地下管線如同城市與鄉村的 “隱形生命線”&#xff0c;承載著電力輸送、供水供氣、通信傳輸等重要功能&#xff0c;默默維系著現代社會的正常運轉。然而&#xff0c;這條 “生命線” 正面臨著諸多潛在威脅…

linux時間同步方案

yum install chrony -y # 配置 chrony 使用國內服務器 sed -i s/^pool.*pool.ntp.org/#&/ /etc/chrony.conf cat >> /etc/chrony.conf <<EOF server ntp.aliyun.com iburst server ntp.tencent.com iburst server ntp.ntsc.ac.cn iburst server time1.cloud.t…

C語言筆記(鵬哥)上課板書+課件匯總(KMP算法的動態規劃簡易處理+字符函數和字符串函數)

一、目錄 kmp動態規劃簡易處理next數組字符函數與字符串函數 一、目錄二、引言C語?標準庫中提供了?系列庫函數 三、字符分類函數&#xff08;字符相關的函數&#xff09;推薦一個網站 四、字符轉換函數&#xff08;字符相關的函數&#xff09;五、strlen&#xff08;字符串相…

Java大模型開發入門 (13/15):擁抱官方標準 - Spring AI框架入門與實踐

前言 到目前為止&#xff0c;我們整個系列的旅程都是在功能強大的LangChain4j框架上構建的。它就像一個裝備齊全的“瑞士軍刀”&#xff0c;為我們提供了構建RAG和Agents所需的所有底層和高層工具。 然而&#xff0c;在Java企業級開發的世界里&#xff0c;有一個名字我們永遠…

Github搜索案例

今天的內容是這個案例的實現&#xff0c;以及其中涉及到的內容&#xff0c;需要全部掌握&#xff0c;比如ref&#xff0c;受控組件&#xff0c;props在組件之中的傳遞&#xff0c;以及Pubsub包的使用這些前端React框架有關的內容。現在進入正題 1.github搜索案例&#xff08;a…

Vue3學習(生命周期,hooks,axios的簡單講解)

一&#xff0c;前言 繼續努力&#xff0c;南方見。 二&#xff0c;生命周期 1.對生命周期的理解 例如&#xff1a;人的生命周期&#xff0c;出生&#xff0c;經歷&#xff0c;死亡 組件的話就是&#xff0c;創建&#xff0c;掛載&#xff0c;更新&#xff0c;銷毀。***在特…

Pytorch實戰四 基于 VGG net 搭建一個串聯的神經網絡結構

系列文章目錄 文章目錄 系列文章目錄前言一、VGG類的搭建1.源碼2.初始化類2.1 初始化函數2.2 前向傳播函數 forward(self,x) 二、卷積補充卷積 前言 對于標準的 VGG net 輸入圖像的尺寸是 24 x 24,進行 32 維的下采樣之后得到一個 7 x 7 的特征圖&#xff0c;然后用 FC 層完成分…

大學專業解讀——計算機

我們繼續&#xff0c;講講排名第二流行的新工科專業——計算機。說到計算機&#xff0c;可能所有人都知道&#xff0c;但具體到細分的專業類別&#xff0c;除了計算機科學&#xff0c;其實大多數人都是不了解的。 序&#xff1a; 計算機主要有如下幾個專業&#xff1a; 計算機…

Bootstrap 5學習教程,從入門到精通, Bootstrap 5 列表組(List Group)語法知識點及案例(14)

Bootstrap 5 列表組(List Group)語法知識點及案例 一、列表組基礎語法 列表組是Bootstrap中用于顯示一系列內容的靈活組件&#xff0c;常用于顯示菜單、導航或任何項目列表。 基本列表組結構 <ul class"list-group"><li class"list-group-item&quo…

FPGA基礎 -- Verilog 命名事件

Verilog 的“命名事件&#xff08;Named Events&#xff09;”機制 進行一次系統、專業的培訓。該機制在 Verilog 中是比較冷門但重要的仿真控制特性&#xff0c;主要用于 模塊間同步、行為仿真觸發、事件通信&#xff0c;在復雜的 Testbench、行為模型中尤為重要。 一、命名事…

《Go語言圣經》結構體

《Go語言圣經》結構體 一、結構體指針的高效應用 在處理大型結構體時&#xff0c;為避免內存復制&#xff0c;通常使用指針傳遞和返回結構體&#xff1a; // 通過指針傳入結構體&#xff0c;避免值拷貝 func Bonus(e *Employee, percent int) int {return e.Salary * percen…

Ascend上如何進行帶寬測試

1 工具安裝 1.1 下載鏈接 https://www.hiascend.com/developer/download/community/result?moduledl%2Bcann 1.2 安裝指令&#xff1a; ./Ascend-mindx-toolbox_{version}_linux-{arch}.run --install設置環境變量&#xff1a; source /usr/local/Ascend/toolbox/set_env.…

生產BUG集

磁盤達到閾值導致ES無法刪除數據 method [POST], host [http://xx.xxx.xxx.xxx:9200], URI [/security_event/_delete_by_query?slices1&requests_per_second-1&ignore_unavailablefalse&expand_wildcardsopen&allow_no_indicestrue&ignore_throttledtru…

基于FastAPI與Selenium的智能開關狀態管理系統實踐

引言 在工業物聯網&#xff08;IIoT&#xff09;與自動化控制場景中&#xff0c;設備狀態的實時監控與自然語言指令執行是提升效率的關鍵。本文將介紹一種基于 FastAPI 和 Selenium 的智能設備狀態管理系統&#xff0c;通過大語言模型&#xff08;LLM&#xff09;解析用戶指令…

主體和債項均為“AAA”等級 海爾消金發行10億金融債

6月18日&#xff0c;繼年內發行ABS、落地ESG掛鉤銀團貸后&#xff0c;海爾消費金融&#xff08;以下簡稱“海爾消金”&#xff09;在金融市場上又邁出重要一步&#xff0c;成功簿記發行2025年首期規模達10億元金融債&#xff0c;且主體信用等級仍為“AAA”。這一舉措為海爾消金…

n8n:輕松自動化您的工作流

借助開源自動化利器 n8n&#xff0c;釋放重復勞動的生產力&#xff01; 引言 n8n 是一款免費、開源的工作流自動化工具&#xff0c;致力于幫助開發者和團隊通過連接各種應用和服務&#xff0c;實現重復任務的自動化處理。 它由 Jan Oberhauser 于 2019 年在德國柏林創建&…

Angular--Hello(TODO)

最近有個小錯誤&#xff0c;因為最近還是在看thingsboard&#xff0c;最近終于看到前端的代碼&#xff0c;突然發現怎么全是ts的文件&#xff0c;仔細一看原來并不是之前認為的AngularJS&#xff0c;而是Angular。。。我tm真的無語了&#xff0c;又要去重新學。。。 Angular的…