美文网首页
Swift中设计模式的实践一:责任链模式

Swift中设计模式的实践一:责任链模式

作者: Supremodeamor | 来源:发表于2017-12-05 10:59 被阅读28次

    本文是对Design Patterns implemented in Swift 3.0的解读和翻译,通过这些案例对Swift中的设计模式进行总结和加深理解。
    本文示例代码都是在Xcode的Playground上运行的。

    什么是设计模式

    设计模式(Design Patterns)是面向对象程序开发过程中总结出来的代码设计方式。设计模式为程序开发所遇到的各种情景提供了最佳解决方案,合理地运用设计模式,可以提高代码的复用性,降低代码的耦合度,提升程序的灵活度等等,从而有效的提高开发效率。

    设计模式按功能大概可分为三类:

    设计模式的浅析和实践

    行为型模式

    责任链模式(Chain Of Responsibility)

    责任链模式用于处理不同的请求(request),每个请求会被不同的程序处理。
    原理:为请求提供统一的方法,请求的接收者则根据不同的请求进行不同处理。多个可以接收请求的对象组成一条链,符合条件的接收者会对请求处理,不符合条件的接收者将请求传递给链的下一个接收者,直到链的最后。
    目的:将请求者与接收者解耦,降低代码耦合度

    示例说明:

    ATM机中存在面额为100、50、20、10元的钞票若干,当向ATM查询是否可以提取任意金额现金时,ATM返回true或false。

    示例:

    import Swift
    import Foundation
    
    
    final class MoneyPile {
    
        let value: Int
        var quantity: Int
        var nextPile: MoneyPile?
    
        init(value: Int, quantity: Int, nextPile: MoneyPile?) {
            self.value = value
            self.quantity = quantity
            self.nextPile = nextPile
        }
    
        func canWithdraw(amount: Int) -> Bool {
    
            var amount = amount
    
            func canTakeSomeBill(want: Int) -> Bool {
                return (want / self.value) > 0
            }
    
            var quantity = self.quantity
    
            while canTakeSomeBill(want: amount) {
    
                if quantity == 0 {
                    break
                }
    
                amount -= self.value
                quantity -= 1
            }
    
            guard amount > 0 else {
                return true
            }
    
            if let next = self.nextPile {
                return next.canWithdraw(amount: amount)
            }
    
            return false
        }
    }
    
    final class ATM {
        private var hundred: MoneyPile
        private var fifty: MoneyPile
        private var twenty: MoneyPile
        private var ten: MoneyPile
    
        private var startPile: MoneyPile {
            return self.hundred
        }
    
        init(hundred: MoneyPile,
               fifty: MoneyPile,
              twenty: MoneyPile,
                 ten: MoneyPile) {
    
            self.hundred = hundred
            self.fifty = fifty
            self.twenty = twenty
            self.ten = ten
        }
    
        func canWithdraw(amount: Int) -> String {
            return "Can withdraw: \(self.startPile.canWithdraw(amount: amount))"
        }
    }
    

    调用及结果:

    // Create piles of money and link them together 10 < 20 < 50 < 100.**
    let ten = MoneyPile(value: 10, quantity: 6, nextPile: nil)
    let twenty = MoneyPile(value: 20, quantity: 2, nextPile: ten)
    let fifty = MoneyPile(value: 50, quantity: 2, nextPile: twenty)
    let hundred = MoneyPile(value: 100, quantity: 1, nextPile: fifty)
    
    // Build ATM.
    var atm = ATM(hundred: hundred, fifty: fifty, twenty: twenty, ten: ten)
    atm.canWithdraw(amount: 310) // Cannot because ATM has only 300
    atm.canWithdraw(amount: 100) // Can withdraw - 1x100
    atm.canWithdraw(amount: 165) // Cannot withdraw because ATM doesn't has bill with value of 5
    atm.canWithdraw(amount: 30)  // Can withdraw - 1x20, 2x10
    

    示例分析:

    1. 将所有同一面额的钱抽象为一个对象,同时作为责任链上的接收者,value为面额值,quantity为该面额的数量,nextPile是其链接的下一个接收者。
    2. canWithdraw作为请求的统一接口,canTakeSomeBill判断当前接收者是否可以处理请求,即是否需要取当前面额的钱。(Int类型相除,除数大于被除数时结果为0)。需要取钱时,通过循环在当前接收者进行取钱,当前接收者处理之后,如果仍有待取金额,则传递给下一个接收者处理。
    3. ATM机类将面额由大到小的顺序创建了接收链,canWithdraw作为请求接口,实际则是调用接收者的canWithdraw方法进行具体的请求处理。

    小结:如果不使用责任链模式,当传入一个取款请求时,完全使用if...else...或者switch执行,整个代码将耦合起来,并且根据不同面额进行相同的操作会导致代码大量冗余和重复,面额变动时,对代码的维护工作也将变得繁重。而使用责任链模式,请求对象只需要根据需要添加责任链上的接收者,而接收者处理请求的逻辑则不需要关心。

    相关文章

      网友评论

          本文标题:Swift中设计模式的实践一:责任链模式

          本文链接:https://www.haomeiwen.com/subject/tdjxixtx.html