(翻譯) 重構(gòu)成模式:用策略模式來替代臃腫的條件邏輯




24bbba066362339b1888592f72f3b41.jpg


原創(chuàng)作者:Yerassyl
原文鏈接:https://medium.com/@Yerazhas/refactoring-to-patterns-replace-conditional-logic-with-strategy-9970e057093a


代碼中最常見的復(fù)雜部分之一是復(fù)雜的條件邏輯.
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?-- Martin Fowler



今天我們將會(huì)探索怎么去用策略模式重構(gòu)條件邏輯代碼。目前已經(jīng)有很多關(guān)于重構(gòu)復(fù)雜條件邏輯代碼的方式,比如分解條件,組合方法,用多態(tài)性代替條件等等。


如果你需要在運(yùn)行時(shí)將一些算法與另一個(gè)算法交換,那么你應(yīng)該選擇策略模式(strategy)類。當(dāng)創(chuàng)建策略模式類的時(shí)候,有2種方式給他們傳數(shù)據(jù):

  • 傳主類
  • 像參數(shù)一樣傳遞數(shù)據(jù)


    我們這里的 Loan 類是用來計(jì)算各種類型貸款的資本的,例如定期貸款,周轉(zhuǎn)金貸款,信用貸款。

class Loan {
    var expiryDate: String?
    var maturityDate: String?
    
    func capital() -> Double {
        if expiryDate != nil && maturityDate != nil {
            return 10.0 * duration() * riskFactor()
        }
        if expiryDate != nil && maturityDate == nil {
            if getUnusedPercentage() > 1.0 {
                return 150.0 * getUnusedPercentage()
            } else {
                return 200.0 * getUnusedPercentage()
            }
        }
        
        return 0.0
    }
    
    func duration() -> Double {
        return 0.0
    }
    
    func riskFactor() -> Double {
        return 0.0
    }
    
    func getUnusedPercentage() -> Double {
        return 5.0
    }
}



這個(gè)類有許多條件邏輯來確定貸款的類型。例如,expiryDate 為空,而且 maturityDate 不空的時(shí)候,就是一個(gè)定期貸款。

然后我們創(chuàng)建抽象的 CapitalStrategy 類(這里是protocol),還有TermLoanCapitalStrategy,RevolverCapitalStrategy子類,他們都實(shí)現(xiàn)自己的capital() -> Double 方法。

protocol CapitalStrategy {
    func capital(loan: Loan) -> Double
    func riskFactor() -> Double
}

extension CapitalStrategy {
    func riskFactor() -> Double {
        return 0.0
    }
}

class RevolverCapitalStrategy: CapitalStrategy {
    func capital(loan: Loan) -> Double {
        return 250 * riskFactor()
    }
}

class TermLoanCapitalStrategy: CapitalStrategy {
    func capital(loan: Loan) -> Double {
        if loan.expiryDate != nil && loan.maturityDate != nil {
            return 10.0 * loan.duration() * riskFactor()
        }
        if loan.expiryDate != nil && loan.maturityDate == nil {
            if loan.getUnusedPercentage() > 1.0 {
                return 150.0 * loan.getUnusedPercentage()
            } else {
                return 200.0 * loan.getUnusedPercentage()
            }
        }
        
        return 0.0
    }
}


最后,我們用靜態(tài)方法來代替構(gòu)造函數(shù)。

final class Loan {
    var expiryDate: String?
    var maturityDate: String?
    private var capitalStrategy: CapitalStrategy
    
    private init(capitalStrategy: CapitalStrategy) {
        self.capitalStrategy = capitalStrategy
    }
    
    static func termLoan() -> Loan {
        return self.init(capitalStrategy: TermLoanCapitalStrategy())
    }
    
    static func revolver() -> Loan {
        return self.init(capitalStrategy: RevolverCapitalStrategy())
    }
    
    func capital() -> Double {
        return capitalStrategy.capital(loan: self)
    }
    
    func duration() -> Double {
        return 0.0
    }
    
    func getUnusedPercentage() -> Double {
        return 5.0
    }
}



就這樣,我們單獨(dú)的方法有了明確的名稱和具體的策略對(duì)象(CapitalStrategy),這個(gè)對(duì)象實(shí)現(xiàn)了 capital() -> Double 方法。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容