重構手法之Replace Temp with Query(以查詢取代臨時變數)

来源:http://www.cnblogs.com/liuyoung/archive/2017/11/18/7840722.html
-Advertisement-
Play Games

返回總目錄 6.4Replace Temp with Query(以查詢取代臨時變數) 概要 你的程式以一個臨時變數保存某一表達式的運算結果。 將這個表達式提煉到一個獨立函數中。將這個臨時變數的所有引用點替換為對函數的調用。此後,新函數就可以被其他函數使用。 動機 臨時變數的問題在於:只在當前函數可 ...



 返回總目錄


6.4Replace Temp with Query(以查詢取代臨時變數)

概要

你的程式以一個臨時變數保存某一表達式的運算結果。

將這個表達式提煉到一個獨立函數中。將這個臨時變數的所有引用點替換為對函數的調用。此後,新函數就可以被其他函數使用。

動機

臨時變數的問題在於:只在當前函數可見。如果你在同類的別的地方訪問這個變數,你就必須重新寫表達式來獲取這個變數,這樣的話你就會在不經意間讓你的函數變得複雜起來。如果將臨時變數替換為一個查詢,那麼同類中所有函數都可以獲得這份信息。

所以如果你想要使用Extract Method,那麼Replace Temp with Query是必不可少的一個步驟。而我們前面介紹的Inline Temp其實是這個手法的一部分,兩者的區別在於Inline Temp已經有了表達式自身,只需要做簡單的替換就可以,需要用表達式本身把臨時變數給去掉。而Replace Temp with Query更加全面,裡面包含了提煉表達式到函數本身,然後替換引用點(Inline Temp)。如果你把所有的臨時變數都替換為一個查詢,你的類的結構和邏輯將非常清晰,這樣將更加有利於你的重構和進行優化。

範例

假設有以下簡單函數:

double GetPrice()
{
   int basePrice = _quantity * _itemPrice;
   double discountFactor;
   if (basePrice > 1000)
   {
       discountFactor = 0.95;
   }
   else
   {
       discountFactor = 0.98;
   }
   return basePrice * discountFactor;
}    

我們現在將basePrice 和discountFactor這兩個臨時變數都替換掉。

先來替換basePrice,將basePrice右側表達式提煉出來,然後使用Inline Temp將basePrice的所有引用點都替換掉,並且把basePrice臨時變數的聲明去掉。

現在代碼變成這樣:

double GetPrice()
{
   double discountFactor;
   if (GetBasePrice() > 1000)
   {
      discountFactor = 0.95;
   }
   else
   {
      discountFactor = 0.98;
   }
   return GetBasePrice() * discountFactor;
 }

private int GetBasePrice()
{
   return _quantity * _itemPrice;
}

再以類似的方法提煉出GetDiscountFactor();

private double GetDiscountFactor()
{
   if (GetBasePrice() > 1000)
   {
       return 0.95;
   }
   return 0.98;
}

最終代碼是這樣的。

double GetPrice()
{
   return GetBasePrice() * GetDiscountFactor();
}

private double GetDiscountFactor()
{
    if (GetBasePrice() > 1000)
    {
        return 0.95;
    }
   return 0.98;
}

private int GetBasePrice()
{
   return _quantity * _itemPrice;
}

可以明顯的看到,這個重構手法對於函數本身來說,提高了清晰度,也讓我們進行後期重構能夠更加便捷。

小結

我們常常在迴圈中用臨時變數保存累加信息。如果是這種情況的話,我們可以將整個迴圈都提煉出來。如果在迴圈中要累加好幾個值,那麼就應該針對每個累加值重覆一遍迴圈。這樣,就可以很方便的將所有臨時變數都替換為查詢。

當然,這樣一來,我們可能擔心性能問題。本來我定義一個臨時變數只需要查詢一次,現在我每次都要去做查詢。這個我們完全不必擔心。重構的目的是讓程式更加清晰,有了更加清晰的程式之後再具體做優化也不遲,況且根據二八原則,僅僅這條查詢語句倘若你系統真的出現了性能問題也不大可能,如果實在是因為這條語句,你也可以把變數再放回去。

 

To Be Continued...


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 在網站運行中,錯誤是不可避免的,錯誤頁的產生也是不可缺少的。 這幾天看了博友的很多文章,自己想總結下我從中學到的和實際中配置的。 首先,需要知道產生錯誤頁的來源,一種是我們的.NET平臺拋出的,一種是網站所依賴的宿主拋出的,一般來講我們所依賴的宿主就是IIS了。 IIS中的錯誤頁入口: 其中的錯誤碼 ...
  • 返回總目錄 6.5Introduce Explaining Variable(引用解釋性變數) 概要 你有一個複雜的表達式。 將該複雜表達式(或其中一部分)的結果放進一個臨時變數,以此變數名稱來解釋表達式用途。 動機 有時候你會遇到一系列複雜的表達式連續運算的時候,這個時候你可能根本招架不住如此長或 ...
  • 上一篇簡單介紹了日誌的使用方法,也僅僅是用來做下學習,更何況只能在console輸出。 NLog已是日誌庫的一員大佬,使用也簡單方便,本文介紹的環境是居於.NET CORE 2.0 ,目前的版本也只有beta版。 一、安裝和配置 1.安裝 命令如下 2.創建配置文件 在web項目根目錄下,創建配置文 ...
  • 1、前言 surging內部使用的是高性能RPC遠程服務調用,如果用json.net序列化肯定性能上達不到最優,所以後面擴展了protobuf,messagepack序列化組件,以支持RPC二進位傳輸. 在這裡需要感謝白紙無字Zonciu,新增了messagepack序列化,讓surging 性能上 ...
  • 1、 在表單需要提交Html的頁面頭部加入 ValidateRequest="false" 2、webConfig 的 <system.web> 節點下配置 ...
  • 前言 c#做winform程式要求生成並列印Excel報告,為了不安裝Office相應組件,我選擇了NPOI來生成Excel報告,用winform的PrintDocument控制項來觸發列印操作,而難點在於如何將excel轉換成Graphics對象,在NPOI中我只找到了excel列印的設置(如橫向/ ...
  • 關於Oracle中使用Entity Framework 6.x Code-First方式開發,請參考博客(菩提樹下的楊過)https://www.cnblogs.com/yjmyzz/p/how-to-use-code-first-in-oracle-with-entity-framework-6. ...
  • 一、背景介紹 環境的局限性: 用戶在使用XX客戶端的時候,必須每臺電腦都安裝列印組件,同時由於XX客戶端使用的是 websocket進行通訊,這就必須限制用戶的電腦瀏覽器必須是IE10.0+以上版本,這種局限性在我們公司倉庫部署實施和用戶體驗極其不好。因此我們必須提供一種解決方案,解決我們業務痛點。 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...