學習重構(5)-簡化條件表達式

来源:https://www.cnblogs.com/youknowzcm/archive/2019/12/07/12002846.html
-Advertisement-
Play Games

1.Decompose Conditional (分解條件表達式)應用場景:你有一個複雜的條件(if-then-else)語句。從if、then、else三個段落中分別提煉出獨立函數。示例:if (date.before(SUMMER_START) || date.after(SUMMER_END) ...


1.Decompose Conditional (分解條件表達式)
應用場景:你有一個複雜的條件(if-then-else)語句。從if、then、else三個段落中分別提煉出獨立函數。
示例:
if (date.before(SUMMER_START) || date.after(SUMMER_END)) {
  charge = quantity * mWinterRate + mWinterServiceCharge;
} else {
  charge = quantity * mSummerRate;
}
重構為:
if (notSummer(date)) {
  charge = winterCharge(quantity);
} else {
  charge = summerCharge(quantity);
}
private boolean notSummer(Date date) {
  return date.before(SUMMER_START) || date.after(SUMMER_END);
}
private double winterCharge(int quantity) {
  return quantity * mWinterRate + mWinterServiceCharge;
}
private double summerCharge(int quantity) {
  return quantity * mSummerRate;
}

2.Consolidate Conditional Expression (合併條件表達式)
應用場景:你有一系列條件測試,都得到相同結果。將這些測試合併為一個條件表達式,並將這個條件表達式提煉成一個獨立函數。
示例:
double disabilityAmount() {
if(mSeniority < 2) {
return 0;
}
if(mMonthsDisabled > 12) {
return 0;
}
if(mIsPartTime) {
return 0;
}
// compute the disability amount ...
}
重構為:
double disabilityAmount() {
  if(isNotEligibleForDisability()) {
    return 0;
  }
  // compute the disability amount ...
}
private boolean isNotEligibleForDisability() {
  return (mSeniority < 2) || (mMonthsDisabled > 12) || mIsPartTime;
}

3.Consolodate Duplicate Conditional Fragments (合併重覆的條件片段)
應用場景:在條件表達式的每個分支上有著相同的一段代碼。將這段重覆代碼搬移到條件表達式之外。
示例:
if(isSpecialDeal()) {
  total = price * 0.95; send();
} else {
  total = price * 0.98; send();
}
重構為:
if(isSpecialDeal()) {
  total = price * 0.95;
} else {
  total = price * 0.98;
}
send();

4.Remove Control Flag (移除控制標記)
應用場景:在一系列布爾表達式中,某個變數帶有“控制標記”的作用。以break語句或return語句取代控制標記。
示例:void checkSecurity(String[] people) {
  boolean found = false;
  for(int i = 0; i < people.length; i++) {
    if(!found) {
      if(people[i].equals("Don")) {
      sendAlert();
      found = true;
    }
    if(people[i].equals("John")) {
      sendAlert();
      found = true;
} } } }
重構為:void checkSecurity(String[] people) {
  for(int i = 0; i < people.length; i++) {
    if(people[i].equals("Don")) {
    sendAlert();
    break;
  }
  if(people[i].equals("John")) {
    sendAlert();
    break;
} } }

5.Replace Nested Conditional with Guard Clauses (以衛語句取代嵌套條件表達式)
應用場景:函數中的條件邏輯使人難以看清正常的執行路徑。使用衛語句表現所有特殊情況。
條件表達式常有兩種表現形式:a)所有分支都屬於正常行為;b)表達分支中只有一種是正常行為,其他都是不常見的情況。如果兩條分支都是正常行為,就應該使用形如if...else...的條件表達式;如果某個條件極其罕見,就應該單獨檢查該條件,併在該條件為真時立刻從函數中返回。這樣的單獨檢查常被稱為“衛語句”。
示例:
double getPayAmount() {
  double result; if(mIsDead) {
    result = deadAmount();
  } else {
    if(mIsSeparated) {
      result = separatedAmount();
    } else {
      if(mIsRetired) {
        result = retiredAmount();
      } else {
        result = normalPayAmount();
} } }
return result;
}

重構為:
double getPayAmount() {
  if(mIsDead) {
    return deadAmount();
  }
  if(mIsSeparated) {
    return separatedAmount();
  }
  if(mIsRetired) {
    return retiredAmount();
  }
  return normalPayAmount();
}

6.Replace Conditional with Polymorphism (以多態取代條件表達式)
應用場景:你手上有個條件表達式,它根據對象類型的不同而選擇不同的行為。將這個條件表達式的每個分支放進一個子類內的覆寫函數中,然後將原始函數聲明為抽象函數。
示例:
double getSpeed() {
  switch(mType) {
    case EUROPEAN: return getBaseSpeed();
    case AFRICAN: return getBaseSpeed() - getLoadFactor() * mNumberOfCoconuts;
    case NORWEGIAN_BLUE: return mIsNailed ? 0 : getBaseSpeed(mVoltage);
  }
  throw new RuntimeException("Should be unreachable.");
}

重構為:
abstract class Bird {
  abstract double getSpeed();
}

class European extends Bird {
  double getSpeed() {
  return getBaseSpeed();
} }

class African extends Bird() {
  double getSpeed() {
  return getBaseSpeed() - getLoadFactor() * mNumberOfCoconuts;
} }

class NorwegianBlue extends Bird {
  double getSpeed() {
  return mIsNailed ? 0 : getBaseSpeed(mVoltage);
} }

7. Introduce Null Object (引入Null對象)
應用場景:你需要再三檢查某對象是否為null,將null值替換為null對象。
示例:
if (custom == null) {
plan = BillingPlan.basic();
} else {
plan = custom.getPlan();
}
重構為:
class Custom {
public Plan getPlan() {
return normalPlan;
}

public boolean isNull() {
return false;
}
}

class NullCustom extends Custom {
public Plan getPlan() {
return BillingPlan.basic();
}

public boolean isNull() {
return true;
}
}

8. Introduce Assertion (引入斷言)
應用場景:某一段代碼需要對程式狀態做出某種假設。以斷言明確表現這種假設。


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

-Advertisement-
Play Games
更多相關文章
  • // 用n的階乘來演示 保存上一步計算的數據,進行下一次計算時候先判斷是否有上次執行過的,如果有直接獲取保存的值然後再進行下一步計算 // n! n*(n-1)*....*2*1 // 0! = 1 // n! = n*(n-1)! // 實現記憶前 var count = 0 // 執行的次數 f ...
  • 運算符 賦值運算符 用於給變數賦值。 y=5;/z=2; 算術運算符 即算數符號,是基本算數運算。+ 加 / - 減/ * 乘/ / 除/ % 取餘數/ ++ 自增(y++先賦值再自增/++y先自增再賦值)/ -- 自減,和自增同理/ 複合運算符 += 加等 x+=y等同於 x=x+y 其它的原理相 ...
  • JavaScript的組成 ·ECMAScript 描述了語言的語法和基本對象/ ·DOM 文檔對象模型,描述處理網頁內容/ BOM 瀏覽器對象模型 描述與瀏覽器進行交互的方法和介面 引入方式/ head標簽內/body標簽內 一般在</body>結束標簽錢插入script的標簽 <script> ...
  • 一、iView(View UI) 1、簡介 官網:https://www.iviewui.com/ 倉庫:https://github.com/view-design/ViewUI iView 與 View UI 本質上是一個東西,隨著版本的升級,iView (4.0)改名為 View UI。是一套 ...
  • 這個博客寫了好多前端的知識,有如下內容 "鏈接" ( ^▽^ )( ^▽^ )( ^▽^ ) "html" "css" "JavaScript" "jQuery" "ajax" "canvas" "nodejs" "mysql" "mongodb" "angular" 還有一些數據結構的知識和pyt ...
  • 作者:個人微信公眾號:程式猿的月光寶盒 項目中使用了Mybatis的PageHelper分頁插件後的js文件 js / 初始化首頁數據 / function initData(pageNo) { //清空原來的數據,找到第一個以外的tr,並移除,用 :gt() $("tr:gt(0)").remov ...
  • 1.Ajax非同步按下回車提交表單;2.isEmpty()判斷input框是否為空 ...
  • 首發於微信公眾號《前端成長記》,寫於 2019.12.06 背景 本文記錄刷題過程中的整個思考過程,以供參考。主要內容涵蓋: 題目分析設想 編寫代碼驗證 查閱他人解法 思考總結 目錄 "100.相同的樹" "101.對稱二叉樹" "104.二叉樹的最大深度" "107.二叉樹的層次遍歷II" "10 ...
一周排行
    -Advertisement-
    Play Games
  • 1. 說明 /* Performs operations on System.String instances that contain file or directory path information. These operations are performed in a cross-pla ...
  • 視頻地址:【WebApi+Vue3從0到1搭建《許可權管理系統》系列視頻:搭建JWT系統鑒權-嗶哩嗶哩】 https://b23.tv/R6cOcDO qq群:801913255 一、在appsettings.json中設置鑒權屬性 /*jwt鑒權*/ "JwtSetting": { "Issuer" ...
  • 引言 集成測試可在包含應用支持基礎結構(如資料庫、文件系統和網路)的級別上確保應用組件功能正常。 ASP.NET Core 通過將單元測試框架與測試 Web 主機和記憶體中測試伺服器結合使用來支持集成測試。 簡介 集成測試與單元測試相比,能夠在更廣泛的級別上評估應用的組件,確認多個組件一起工作以生成預 ...
  • 在.NET Emit編程中,我們探討了運算操作指令的重要性和應用。這些指令包括各種數學運算、位操作和比較操作,能夠在動態生成的代碼中實現對數據的處理和操作。通過這些指令,開發人員可以靈活地進行算術運算、邏輯運算和比較操作,從而實現各種複雜的演算法和邏輯......本篇之後,將進入第七部分:實戰項目 ...
  • 前言 多表頭表格是一個常見的業務需求,然而WPF中卻沒有預設實現這個功能,得益於WPF強大的控制項模板設計,我們可以通過修改控制項模板的方式自己實現它。 一、需求分析 下圖為一個典型的統計表格,統計1-12月的數據。 此時我們有一個需求,需要將月份按季度劃分,以便能夠直觀地看到季度統計數據,以下為該需求 ...
  • 如何將 ASP.NET Core MVC 項目的視圖分離到另一個項目 在當下這個年代 SPA 已是主流,人們早已忘記了 MVC 以及 Razor 的故事。但是在某些場景下 SSR 還是有意想不到效果。比如某些靜態頁面,比如追求首屏載入速度的時候。最近在項目中回歸傳統效果還是不錯。 有的時候我們希望將 ...
  • System.AggregateException: 發生一個或多個錯誤。 > Microsoft.WebTools.Shared.Exceptions.WebToolsException: 生成失敗。檢查輸出視窗瞭解更多詳細信息。 內部異常堆棧跟蹤的結尾 > (內部異常 #0) Microsoft ...
  • 引言 在上一章節我們實戰了在Asp.Net Core中的項目實戰,這一章節講解一下如何測試Asp.Net Core的中間件。 TestServer 還記得我們在集成測試中提供的TestServer嗎? TestServer 是由 Microsoft.AspNetCore.TestHost 包提供的。 ...
  • 在發現結果為真的WHEN子句時,CASE表達式的真假值判斷會終止,剩餘的WHEN子句會被忽略: CASE WHEN col_1 IN ('a', 'b') THEN '第一' WHEN col_1 IN ('a') THEN '第二' ELSE '其他' END 註意: 統一各分支返回的數據類型. ...
  • 在C#編程世界中,語法的精妙之處往往體現在那些看似微小卻極具影響力的符號與結構之中。其中,“_ =” 這一組合突然出現還真不知道什麼意思。本文將深入剖析“_ =” 的含義、工作原理及其在實際編程中的廣泛應用,揭示其作為C#語法奇兵的重要角色。 一、下劃線 _:神秘的棄元符號 下劃線 _ 在C#中並非 ...