1. 程式人生 > >.NET Core TDD 前傳: 編寫易於測試的程式碼 -- 依賴項

.NET Core TDD 前傳: 編寫易於測試的程式碼 -- 依賴項

第1篇: 講述了如何創造"縫".  "縫"(seam)是需要知道的概念.

本文是第3篇, 講述依賴項和迪米特法則.

迪米特法則 (Law of Demeter)

還是使用建造汽車的例子. 生產汽車的時候需要輪胎, 組裝時需要什麼型號的輪胎, 就請求該型號的輪胎, 然後相關人員會從庫房把該型號的輪胎送到產線用於組裝. 

我相信很少有汽車廠會這樣做: 生產汽車時, 汽車組裝工拿著庫房的鑰匙, 自己去庫房從各種各樣的輪胎中找所需要的型號..

這就是違反迪米特法則的一個例子.

迪米特法則大概的意思是: "只訪問你自己建立的物件, 或者作為引數傳給你的物件. 不要通過其它物件間接的訪問物件"

用一句話歸納迪米特法則就是: "只與直系朋友交談, 不要和陌生人交談".

注意: 迪米特法則其實並不算嚴格的法則, 它只是一個非常有益的指導性原則. 

存在的問題

用程式碼形容上面的例子就是: 

這違反了迪米特法則, 導致了以下問題:

  • 造成了BenzCar和Warehouse以及MichelinTire之間的緊耦合, 而實際上BenzCar只需要MichelinTire.
  • 測試時, 設定會很麻煩. 程式碼裡Warehouse是直系朋友, MichelinTire是陌生人. 我們需要為Warehouse和MichelinTire同時設定測試替身.
  • 真正需要的依賴項沒有明確在建構函式裡定義
    . 這裡Warehouse相當於是一個容器, 測試時, 我們可能會不知道要為Warehouse裡的哪個東西做測試替身.

危險訊號

下列寫法可能意味著您的程式碼違反了迪米特法則:

  • 程式碼裡有這樣的呼叫: "warehouse.getTire.getMichelinTire", 有一連串的點".". 但是有時候這樣做是可以的, 例如流暢(fluent)形式的建造者模式就可以, 因為fluent介面通常會返回物件本身, 然後再去使用該物件.
  • 依賴於容器. 例如把 IocContainer作為依賴注入使用. 
  • 依賴項的名稱為XxxContext, XxxContainer, XxxEnvironment, XxxManager, XxxServiceLocator
    .
  • 測試時需要建立返回mocks的mock物件.
  • 測試時的設定非常麻煩.

解決辦法

解決辦法就是遵從迪米特法則.

只注入我們直接需要的依賴項, 直接使用它們. 這樣就會保證依賴項很明確, 測試的時候一眼就能看出依賴於哪些物件.

程式碼示例

例子一

下面這個違反了迪米特法則, 直接注入的是Warehouse, 而實際用到的卻是MichelinTire:

正確的做法是, 注入直接使用的依賴項:

例子二

下面的程式碼也違反了迪米特法則, 它注入了一個容器類的物件:

這個ServiceLocator就相當於是一個容器. 這樣用的話, 寫測試的人可能根本無法知道需要使用容器裡面的哪個物件.

你也許會說這樣做靈活(我以前也經常這樣做), 但是重構的時候, 這裡很容易出錯, 因為根本看不出來真正依賴的是哪個物件.

正確的做法還是應該注入直接需要的依賴項:

Law of Demeter相關的內容就簡單介紹這些.

相關推薦

.NET Core TDD : 編寫易於測試的代碼 -- 縫

廠商 關鍵字 com omap 註入 大堆 解決 而是 不知道 有時候不是我們不想做單元測試, 而是這代碼寫的實在是沒法測試.... 舉個例子, 如果一輛汽車在產出後沒完成測試, 那麽沒人敢去駕駛它. 代碼也是一樣的, 如果項目未能進行該做的測試, 那麽客戶就不敢去使用它

.NET Core TDD : 編寫易於測試的代碼 -- 構建對象

rep 文章 建立 ini 代碼 ali 請求 uid 依賴項 該系列第1篇: 講述了如何創造"縫". "縫"(seam)是需要知道的概念. 本文是第2篇, 介紹的是如何避免在構建對象時寫出不易測試的代碼. 本文的概念性內容大部分都來自Misko Hevery的這篇博客

.NET Core TDD : 編寫易於測試程式碼 -- 構建物件

該系列第1篇: 講述了如何創造"縫".  "縫"(seam)是需要知道的概念. 本文是第2篇, 介紹的是如何避免在構建物件時寫出不易測試的程式碼. 本文的概念性內容大部分都來自Misko Hevery的這篇部落格文章. 構建 還是用上文裡汽車的例子. 通常情況下, 我們是先去建造汽車, 組裝好汽車後,

.NET Core TDD : 編寫易於測試程式碼 -- 縫

有時候不是我們不想做單元測試, 而是這程式碼寫的實在是沒法測試.... 舉個例子, 如果一輛汽車在產出後沒完成測試, 那麼沒人敢去駕駛它. 程式碼也是一樣的, 如果專案未能進行該做的測試, 那麼客戶就不敢去使用它, 即使使用了也會遇到“車禍”.  為什麼要測試/測試的好處 它可以儘早發現bug,

.NET Core TDD : 編寫易於測試程式碼 -- 單一職責

第1篇: 講述了如何創造"縫".  "縫"(seam)是需要知道的概念. 本文是第5篇, 也是最後一篇, 介紹的是單一職責 類做了太多的工作 例子, 某軟體公司, 原有專案開發, 測試, 售前, 售後, 財務等員工. 後來由於公司沒錢, 裁掉了測試, 讓開發兼職; 過了段時間, 又裁掉了

.NET Core TDD : 編寫易於測試程式碼 -- 全域性狀態

第1篇: 講述了如何創造"縫".  "縫"(seam)是需要知道的概念. 本文是第4篇, 將介紹全域性狀態引起的問題. 全域性狀態 全域性狀態, 也可以叫做應用程式狀態, 它是一組變數, 這些變數維護著應用程式的高階狀態. 在程式裡, 全域性狀態可能都存放在一個全域性狀態物件裡, 例如AS

.NET Core TDD : 編寫易於測試程式碼 -- 依賴

第1篇: 講述了如何創造"縫".  "縫"(seam)是需要知道的概念. 本文是第3篇, 講述依賴項和迪米特法則. 迪米特法則 (Law of Demeter) 還是使用建造汽車的例子. 生產汽車的時候需要輪胎, 組裝時需要什麼型號的輪胎, 就請求該型號的輪胎, 然後相關人員會從庫房把該型號的輪

.NET Core TDD OA 信用盤平臺搭建: 編寫易於測試的代碼構建對象

建造者 五個 包括 值類型 bject 方法 之前 關系 服務 聯系方式:QQ:2747044651 網址http://zhengtuwl.com常情況下, 我們是先去建造汽車, 組裝好汽車後, 我們再去駕駛它. 軟件開發也類似, 我們應該把對象構造完畢之後, 再去用它.

輕松掌握VS Code開發.Net Core及創建Xunit單元測試

blog logs 寫文章 編譯 分享 單獨 etc 2.0 ren 前言 本篇文章主要還是介紹使用 VS Code 進行.Net Core開發和常用 CLI命令的使用,至於為啥要用VS Code ,因為它是真的是好看又好用 :) ,哈哈,主要還是為了跨平臺開發做準備。 開

學習 ASP.NET Core 2.1:集成測試中使用 WebApplicationFactory

UNC enc sta 測試 修改 構造 creat -a msdn WebApplicationFactory 是 ASP.NET Core 2.1 新特性 MVC functional test infrastructure 中帶來的新東東,它封裝了 TestServe

ASP.NET Core 入門教程 5、ASP.NET Core MVC 檢視值入門

一、前言 1、本教程主要內容 ASP.NET Core MVC 檢視引擎(Razor)簡介 ASP.NET Core MVC 檢視(Razor)ViewData使用示例 ASP.NET Core MVC 檢視(Razor)ViewBag使用示例 ASP.NET Core NVC 檢視(Razor)強型別傳值

ASP NET Core檔案上與下載 多種上方式

                                                                                                    前言前段時間專案上線,實在太忙,最近終於開始可以研究研究ASP.NET Core了.打算寫個系列,但是還沒想好

ASP.NET Core檔案上與下載(多種上方式)

前言前段時間專案上線,實在太忙,最近終於開始可以研究研究ASP.NET Core了.打算寫個系列

.Net Core 檔案上與下載

參考連結: 遇到的問題: 按 參考1 中測試,下載檔案檔名總是變成方法名(DownloadFile),並且沒有副檔名,儲存後改副檔名可正常檢視。 參考 連結3 測試無效,未解決下載問題。 參考 連結2,問題解決。 程式碼實現如下: 檔案上傳 [

.NET CORE與Spring Boot編寫控制檯程式應有的優雅姿勢

本文分別說明.NET CORE與Spring Boot 編寫控制檯程式應有的“正確”方法,以便.NET程式設計師、JAVA程式設計師可以相互學習與加深瞭解,注意本文只介紹用法,不會刻意強調哪種語言或哪種框架寫的控制檯程式要好。 本文所說的編寫控制檯程式應有的“正

.NetCore技術研究-.NET Core遷移的準備工作

前段時間遷移.NET Core做了大量的試水和評估,今天整理一下分享給大家。大致有以下幾個部分: 1. .NET Core的由來 2. 為什麼要遷移.NET Core 3. .NET Core3.X主要特性 4. .NET Standard和.NET Core 5. .NET Core Roadma

asp.net core 使用 TestServer 來做整合測試

# asp.net core 使用 TestServer 來做整合測試 ## Intro 之前我的專案裡的整合測試是隨機一個埠,每次都真實的啟動一個 WebServer,之前也有看到過微軟文件上 `TestServer` 的介紹,當時沒仔細看過以為差不多就沒用,一直是啟動了一個真正的 WebServer

(7)學習筆記 ) ASP.NET CORE微服務 Micro-Service ---- 利用Polly+AOP+依賴註入封裝的降級框架

tostring methods summary bstr 判斷 KS foreach public tde 創建簡單的熔斷降級框架 要達到的目標是: 參與降級的方法參數要一樣,當HelloAsync執行出錯的時候執行HelloFallBackAsync方法。 pu

利用.net Core 對程序集中的類 進行統一依賴註入

info lis posit sem main HERE tasks ner assembly 1.創建特性 用於標註依賴註入 using Microsoft.Extensions.DependencyInjection; using System; using Syst

Net core 2.x - docker(for windows)-linux配置及目發布

區別 默認 context aml 配置說明 nds cor 開篇 -- 將.net core2.x+sqlserver項目發布到docker.呵呵,操作很自如,如下. 1.羅嗦幾句 在跑起來之前浪費了不少時間和精力,起初是將docker for windows的環境轉