責任鏈模式
簡介:將請求傳遞給一個接受者鏈,由鏈將請求流傳給目標對象
背景
繼續(xù)上次的問題背景,Jack的水果店現(xiàn)在支持同時疊加使用不同的優(yōu)惠券。
實現(xiàn)設計

設計
1、calculate方法內(nèi),判斷next結(jié)點不為null,則繼續(xù)調(diào)用next.calculate;
2、客戶端調(diào)用時,負責初始化整個責任鏈。
注:當出現(xiàn)多個對象可以處理同一個請求時,適合責任鏈模式。
代碼實例
/**
*@Description
*@Author PC
*@QQ 1578684787
*/
abstract class MultyDiscount(val nextMultyDiscount: MultyDiscount?):Discount {
abstract override fun calculate(money:Int):Int
}
/**
* 節(jié)假日一律減5元
*/
class HolidayMultyDiscount(nextMultyDiscount: MultyDiscount?):MultyDiscount(nextMultyDiscount) {
override fun calculate(money: Int): Int {
var relMoney = 0
if (money>10){
println("假日一律減5元")
relMoney = money-5
}
if (nextMultyDiscount !=null){
return nextMultyDiscount.calculate(relMoney)
}
return relMoney
}
}
class SecondMultyDiscount(nextMultyDiscount: MultyDiscount?):MultyDiscount(nextMultyDiscount) {
override fun calculate(money: Int): Int {
var relMoney = money
println("第二單打九折")
relMoney = (relMoney*0.9).toInt()
if (nextMultyDiscount!=null){
return nextMultyDiscount.calculate(relMoney)
}
return relMoney
}
}
class FullMultyDiscount(nextMultyDiscount: MultyDiscount?):MultyDiscount(nextMultyDiscount) {
override fun calculate(money: Int): Int {
var relMoney = money
if (money>200){
println("優(yōu)惠滿減20元")
relMoney -= 20
}
if (nextMultyDiscount !=null){
return nextMultyDiscount.calculate(relMoney)
}
return relMoney
}
}
測試
class ChainCartClient{
companion object{
private var multyDiscount:MultyDiscount = FullMultyDiscount(null)
init {
multyDiscount = SecondMultyDiscount(multyDiscount)
multyDiscount = HolidayMultyDiscount(multyDiscount)
}
@JvmStatic
fun main(args: Array<String>) {
val banana = Banana("香蕉",40)
val apple = Apple("蘋果",50)
val kiwifruit = Banana("獼猴桃",80)
val shopping = OnlineShopping(listOf(banana,apple,kiwifruit))
shopping.setDiscount(multyDiscount)
shopping.submitOrder()
}
}
}
測試結(jié)果

image.png
應用場景
- 對個對象處理同一請求時,但是具體由哪個對象去處理需要運行時做判斷。
- 具體處理者不明確的情況下,向這組對象提交了一個請求。
在Android中的應用:1、Android中的時間分發(fā)機制就是類似于責任鏈模式;2、OKhttp中對請求的處理也是用到了責任鏈模式。
優(yōu)點
- 代碼的解耦,請求者和處理者隔離分開。
- 易于擴展,新增處理者往鏈上加結(jié)點即可。
缺點
- 責任鏈過長的話,或者責任鏈上的結(jié)點判斷處理時間太長的話會影響性能,特別是遞歸循環(huán)的時候。
- 請求有可能遍歷完鏈都得不到處理。