概念:
策略模式属于对象的行为模式。其用意是针对一组算法,将每一个算法封装到具有共同接口的独立的类中,从而使得它们可以相互替换。策略模式使得算法可以在不影响到客户端的情况下发生变化。
类图:
● 环境(Context)角色:持有一个Strategy的引用。
● 抽象策略(Strategy)角色:这是一个抽象角色,通常由一个接口或抽象类实现。此角色给出所有的具体策略类所需的接口。
● 具体策略(ConcreteStrategy)角色:包装了相关的算法或行为。
使用场景:
假设某个商店对所有的高级会员提供每本20%的促销折扣;对中级会员提供每本10%的促销折扣;对初级会员没有折扣;计算同一个价格不同策略下的输出
/**
* @Author: fc
* @Date: 19:30 2017/10/25
*/
interface MemberStrategy {
/**
* 计算图书的价格
* @param booksPrice 图书的原价
* @return 计算出打折后的价格
*/
fun calcPrice(booksPrice: Double): Double
}
class PrimaryMemberStrategy:MemberStrategy {
override fun calcPrice(booksPrice: Double): Double {
println("对于初级会员的没有折扣")
return booksPrice
}
}
class AdvancedMemberStrategy:MemberStrategy {
override fun calcPrice(booksPrice: Double): Double {
println("对于高级会员的折扣为20%")
return booksPrice * 0.8
}
}
class Price(strategy: MemberStrategy) {
//持有一个具体的策略对象
var mStrategy: MemberStrategy? = strategy
fun setMemberStrategy(strategy: MemberStrategy){
mStrategy = strategy
}
fun calculate(booksPrice: Double): Double {
return mStrategy?.calcPrice(booksPrice)!!
}
}
测试类:
fun main(args: Array<String>) {
val strategy = AdvancedMemberStrategy()
val price = Price(strategy)
println("图书的最终价格为:"+price.calculate(100.00))
val primaryStrategy = PrimaryMemberStrategy()
price.setMemberStrategy(primaryStrategy)
println("图书的最终价格为:"+price.calculate(100.00))
}
运行结果:
对于高级会员的折扣为20%
图书的最终价格为:80.0
对于初级会员的没有折扣
图书的最终价格为:100.0
优点:
1.策略类之间可以自由切换,由于策略类实现自同一个抽象,所以他们之间可以自由切换。
2.易于扩展,增加一个新的策略对策略模式来说非常容易,基本上可以在不改变原有代码的基础上进行扩展。
3.易于维护,使用策略模式可以避免使用多重条件(if-else)语句。
缺点:
1.客户端必须知道所有的策略类,并自行决定使用哪一个策略类。
2.类的个数会比较多,因为策略模式把每个具体的策略实现都单独封装成为类
策略模式是一种简单常用的模式,我们在进行开发的时候,会经常有意无意地使用它,一般来说,策略模式不会单独使用,跟模版方法模式、工厂模式等混合使用的情况比较多。