策略模式
简介:通过选择策略类,来执行不同算法分支。核心是通过注入对象,改变行为。
背景
继续上次的故事背景,Jack的水果店新增加优惠卷活动,所以整个程序流程在结算的时候又多了扣去优惠,并且优惠服务是可选择的。
实现设计
image.png1、将每一种优惠策略,单独成一个独立对象,独立出来。
2、使用方法通过选择不同的组件,达到不同的行为。
代码实例
/**
*@Description
*@Author PC
*@QQ 1578684787
*/
interface Discount {
fun calculate(money:Int):Int
}
class FullDiscount:Discount {
override fun calculate(money: Int): Int {
if (money>200){
println("优惠减免20元")
return money-20
}
return money
}
}
class NewerDiscount:Discount {
override fun calculate(money: Int): Int {
println("新顾客尊享满100减20")
if (money>100){
return money-20
}
return money
}
}
class SecondDiscount:Discount {
override fun calculate(money: Int): Int {
val balance = money*0.9
return balance.toInt()
}
}
/**
*@Description
*@Author PC
*@QQ 1578684787
*/
abstract class ShoppingCart(open var products:List<Fruit> = ArrayList()) {
private var discount:Discount?=null
@JvmName("setDiscount1")
fun setDiscount(discount: Discount){
this.discount =discount
}
//提交订单
fun submitOrder(){
//计算商品金额
var money = balance()
money = discount!!.calculate(money)
println("需要支付的总金额为${money}元")
//保存订单
pay(money)
//送货上门
sendHome()
}
//计算金额
private fun balance():Int{
var money:Int = 0
println("商品清单:")
for (fruit in products){
Factory.pack(fruit,fruit.price)
println("${fruit.name},${fruit.price}")
money+=fruit.price
}
return money
}
private fun sendHome(){
println("三公里以内,免费送货上门")
}
//提交保存
abstract fun pay(money:Int)
}
测试
class ShoppingCartClient {
companion object{
var discounts:MutableMap<String,Discount> = mutableMapOf()
init {
discounts["full"] = FullDiscount()
discounts["newer"] = NewerDiscount()
discounts["second"] = SecondDiscount()
}
@JvmStatic
fun main(args: Array<String>) {
val banana = Banana("香蕉",40)
val apple = Apple("苹果",50)
val banana2 = Banana("黄金蕉",60)
val shopping = OnlineShopping(listOf(banana,apple,banana2))
discounts["newer"]?.let { shopping.setDiscount(it) }
shopping.submitOrder()
}
}
}
测试结果
测试结果
应用场景
- 同一个问题具有不同算法时,即仅仅是具体的实现细节不同时。
- 对用户隐藏具体策略的实现细节,彼此完全独立;提高算法的保密性与安全性。
- 一个类拥有很多行为,而又需要使用if-else或者switch语句来选择具体行为时。使用策略模式把这些独立行为独立到具体的策略类中,可以避免多重选择的结构。
Android中的应用:我们使用的ListView需要设置Adapter,而这个Adapter可以根据我们的实际需求使用SimpleAdapter、ArrayAdapter等等,这里就运用到策略模式。
优点
- 策略类可以互相替换,由于策略类都实现同一个接口,因此他们能够互相替换。
- 耦合度低,方便扩展,增加一个新的策略只需要添加一个具体的策略类即可,基本不需要改变原有的代码,符合开闭原则。
- 避免使用多重条件选择语句(if-else或者switch)。
缺点
- 策略的增多会导致子类变化更多
- 客户端必须知道所有的策略类,并自行决定使用哪一个策略类。
参考文章
Android的设计模式-策略模式
网友评论