Swift设计模式——责任链模式
2017-05-26 本文已影响0人
晓晓魔导师
什么是责任链模式?
顾名思义,责任链模式(Chain of Responsibility Pattern)为请求创建了一个接收者对象的链。这种模式给予请求的类型,对请求的发送者和接收者进行解耦。这种类型的设计模式属于行为型模式。
在这种模式中,通常每个接收者都包含对另一个接收者的引用。如果一个对象不能处理该请求,那么它会把相同的请求传给下一个接收者,依此类推。
<br />
使用场景:
- 有多个对象可以处理同一个请求,具体哪个对象处理该请求由运行时刻自动确定。
- 在不明确指定接收者的情况下,向多个对象中的一个提交一个请求。
- 可动态指定一组对象处理请求。
<br />
示例:
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 //100面额的钱堆
private var fifty: MoneyPile //50面额的钱堆
private var twenty: MoneyPile //20面额的钱堆
private var ten: MoneyPile //10面额的钱堆
//优先寻找的钱堆
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))"
}
}
//创建如下钱堆,并将它们整理(连接)在一起。
let ten = MoneyPile(value: 10, quantity: 6, nextPile: nil) //里面有6个面额为10元的金币
let twenty = MoneyPile(value: 20, quantity: 2, nextPile: ten) //里面有2个面额为20元的金币
let fifty = MoneyPile(value: 50, quantity: 2, nextPile: twenty) //里面有2个面额为50元的金币
let hundred = MoneyPile(value: 100, quantity: 1, nextPile: fifty) //里面有1个面额为100元的金币
//创建银行
var atm = ATM(hundred: hundred, fifty: fifty, twenty: twenty, ten: ten)
//
atm.canWithdraw(amount: 300) //输出: Can withdraw: true ,因为银行里金币总价值300
atm.canWithdraw(amount: 130) //输出: Can withdraw: true,因为可以取1个100面额的金币+1个20面额的金币+1个10面额的金币组成。
atm.canWithdraw(amount: 105) //输出:Can withdraw: false, 因为没有一个钱堆有面额为5的金币。
<br />
优点
- 降低耦合度。它将请求的发送者和接收者解耦。
- 简化了对象。使得对象不需要知道链的结构。
- 增强给对象指派职责的灵活性。通过改变链内的成员或者调动它们的次序,允许动态地新增或者删除责任。
- 增加新的请求处理类很方便。
缺点
- 不能保证请求一定被接收。
- 系统性能将受到一定影响,而且在进行代码调试时不太方便,可能会造成循环调用。
- 可能不容易观察运行时的特征,有碍于除错。