《重構-代碼整潔之道TypeScript版》第三天


今天讓咱們來繼續第3天,老規矩先來回顧一下昨天咱們都實現了哪些:html

  • Change Reference to Value(將引用對象改成值對象) 
  • Change Value to Reference(將值對象改成引用對象) 
  • Collapse Hierarchy(摺疊繼承體系)

(圖片:博格達峯)前端

什麼是重構 ?

簡單理解就是不改變軟件可觀察行爲的前提下,改善其內部結構,以提升理解性和下降修改爲本。面試


1. 這是以下咱們要實現的目標任務列表(天天進步一點點⏰)  

  • Consolidate Conditional Expression(合併條件表達式) 
  • Consolidate Duplicate Conditional Fragments(合併重複的條件片斷)  
  • Convert Procedural Design to Objects(將過程化設計轉化爲對象設計)  
  • Decompose Conditional(分解條件表達式) 
  • Duplicate Observed Data(複製「被監視數據」)  
  • Encapsulate Collection(封裝集合)  
  • Encapsulate Downcast(封裝向下轉型)  
  • Encapsulate Field(封裝字段) 
  • Extract Class(提煉類) 
  • Extract Hierarchy(提煉繼承體系) 
  • Extract Interface(提煉接口)  
  • Extract Method(提煉函數)  
  • Extract Subclass(提煉子類) 
  • Extract Superclass(提煉超類)  
  • Form Template Method(塑造模板函數)  
  • Hide Delegate(隱藏「委託關係」)  
  • Hide Method(隱藏函數)  
  • Inline Class(將類內聯化)  
  • Inline Method(內聯函數)  
  • Inline Temp(內聯臨時變量) 
  • Introduce Assertion(引入斷言)  
  • Introduce Explaining Variable(引入解釋性變量)  
  • Introduce Foreign Method(引入外加函數) 
  • Introduce Local Extension(引入本地擴展)  
  • Introduce Null Object(引入Null對象) 
  • Introduce Parameter Object(引入參數對象)  
  • Move Field(搬移字段)  
  • Move Method(搬移函數) 
  • Parameterize Method(令函數攜帶參數)  
  • Preserve Whole Object(保持對象完整) 
  • Pull Up Constructor Body(構造函數本體上移) 
  • Pull Up Field(字段上移) 
  • Pull Up Method(函數上移)  
  • Push Down Field(字段下移)  
  • Push Down Method(函數下移)  
  • Remove Assignments to Parameters(移除對參數的賦值)  
  • Remove Control Flag(移除控制標記) 
  • Remove Middle Man(移除中間人) 
  • Remove Parameter(移除參數)  
  • Remove Setting Method(移除設值函數) 
  • Rename Method(函數更名)  
  • Replace Array with Object(以對象取代數組)  
  • Replace Conditional with Polymorphism(以多態取代條件表達式) 
  • Replace Constructor with Factory Method(以工廠函數取代構造函數)  
  • Replace Data Value with Object(以對象取代數據值)  
  • Replace Delegation with Inheritance(以繼承取代委託) 
  • Replace Error Code with Exception(以異常取代錯誤碼)  
  • Replace Exception with Test(以測試取代異常)  
  • Replace Inheritance with Delegation(以委託取代繼承) 
  • Replace Magic Number with Symbolic Constant(以字面常量取代魔法數)  
  • Replace Method with Method Object(以函數對象取代函數) 
  • Replace Nested Conditional with Guard Clauses(以衛語句取代嵌套條件表達式)  
  • Replace Parameter with Explicit Methods(以明確函數取代參數)  
  • Replace Parameter with Methods(以函數取代參數) 
  • Replace Record with Data Class(以數據類取代記錄)  
  • Replace Subclass with Fields(以字段取代子類) 
  • Replace Temp with Query(以查詢取代臨時變量)  
  • Replace Type Code with Class(以類取代類型碼)  
  • Replace Type Code with State/Strategy(以State/Strategy取代類型碼)  
  • Replace Type Code with Subclasses(以子類取代類型碼) 
  • Self Encapsulate Field(自封裝字段)  
  • Separate Domain from Presentation(將領域和表述/顯示分離) 
  • Separate Query from Modifier(將查詢函數和修改函數分離) 
  • Split Temporary Variable(分解臨時變量)  
  • Substitute Algorithm(替換算法)  
  • Tease Apart Inheritance(梳理並分解繼承體系)  

2. Consolidate Conditional Expression(合併條件表達式) 

描述🍏:你有一些列的條件測試都獲得了相同的結果,你能夠將這些測試合併爲一個條件表達式,並將這個條件表達式提煉爲一個獨立的函數。算法

動機🍃: 檢查條件各不相同,行爲一直就應該使用「邏輯或」和「邏輯與」將他們合併爲一個條件表達式。typescript

interface ConfigFn {
  (): number;
}
const disabilityAmount: ConfigFn = (): number => {
  if (_seniority < 2) return 0;
  if (_monthsDisabled > 12) return 0;
  if (_isPartTime) return 0;
};
複製代碼

在這段代碼中,咱們看到一連串的條件檢查,它們都作同一件事。上述條件檢查等價於一個以邏輯或鏈接起來的語句:shell

const disabilityAmount: ConfigFn = (): number => {
    (_seniority<2)||(_monthsDisabled>12)||(_isPartTime))return 0;
}
//繼續改造
const isNotEligible = ():boolean=>{
    return  (_seniority<2)||(_monthsDisabled>12)||(_isPartTime));
} 
const onVacation = ():boolean=>{} 
const disabilityAmount = (): number => {
  // 這裏也可使用邏輯與繼續更復雜的應用
  // if(isNotEligible){
  if(isNotEligible && onVacation){
        return 0;
   }
}
複製代碼

3. Consolidate Duplicate Conditional Fragments(合併重複的條件片斷)

描述🐥:在條件表達式的每一個分支上有着相同的一段代碼,將這段代碼搬到條件表達式以外。編程

動機🐈:移除相同的重複代碼才更更清楚的代表哪些東西隨條件的變化而變化,哪些東西保持不變。json

// 簡單版本 好比koa2的輸出
if(flag){
    const data = "老袁";
    res.end(data)
}else{
    const data = {
        "message":"老袁"
    }
    res.end(data)
}

//改造後
let data = "默認信息";
if(flag){
    data = "老袁";
}else{
    data = {
        "message":"老袁"
    }
}
res.end(data)
複製代碼

咱們在來看看複雜的版本:數組

//編寫.jscpd.json
{
  "mode": "strict",
  "threshold": 0,
  "reporters": ["html", "console", "badge"]
}
複製代碼
yarn add jscpd -D
yarn add jscpd-badge-reporter -D
jscpd ./src
複製代碼

補一張效果圖:markdown

固然這只是一個小工具,你們想專業的刷起來Sonar。

4. Convert Procedural Design to Objects(將過程化設計轉化爲對象設計) 

描述🌾:你手上有一些傳統過程化的代碼,沒有任何封裝。現咱們可將數據記錄變成對象,將大塊的行爲分紅小塊,並將行爲移入到相關對象之中。

動機🐻:有一次我看到過帶的一個實行生一個純的函數120多行,這個時候咱們就能夠用一些小型對象改變宿主對象的行爲。長長的函數通常都是你下手這條規定的最佳時機。

這裏我就不囉嗦了,但願你們有時間能夠靜下來在好好看看除了封裝、繼承、多態外基於SOLID的設計,其實足夠了。

函數式編程和SOLID實際上是相輔相成的。

前端圈最好用的刷題工具

​ 掃碼 get 前端圈刷題神器,解鎖800+道 有答案和解析的 前端面試真題,所有來自BAT、TMD等一二線互聯網公司。 ​

​ 回顧第一天的文章👉 :《重構-代碼整潔之道TypeScript版》第一天

回顧次日的文章👉 :《重構-代碼整潔之道TypeScript版》次日


每一次咱們不會給你們寫過多的重構規則,力求天天用幾分鐘時間真正去理解了重構。明天見~若是您有什麼意見和反饋,歡迎您在下方留言。

做者 【老袁】 2020 年 07月 30日

相關文章
相關標籤/搜索