策略模式在《Design Patterns: Elements of Reusable Object-Oriented Software》的定义
Define a family of algorithms, encapsulate each one, and make them inter changeable.Strategy lets the algorithm vary independently from clients that use it.
策略模式中的角色
- Strategy策略接口或者(抽象策略类),定义策略执行接口
- ConcreteStrategy具体策略类
- Context上下文类,持有具体策略类的实例,并负责调用相关的算法
对于策略模式的优缺点或者代码样例可以参考电子工业出版社的《Java 与模式》和清华大学出版社的《Java设计模式》
下面将重点介绍在函数式编程中如何实现策略模式
object StrategyPattern {
//计算代数平均值
def strategyOne(scores: Array[Double]): Double = {
var sum: Double = 0
scores.foreach(s => sum = sum + s)
sum/scores.length
}
//计算几何平均值
def strategyTwo(scores: Array[Double]): Double = {
var multi: Double = 1
scores.foreach(s => multi = multi * s)
Math.pow(multi, 1.0/scores.length)
}
//返回具体的计算方法
def setStrategy(concreteStrategy: (Array[Double]) => Double) = {
(scores: Array[Double]) => {
concreteStrategy(scores)
}
}
def main(args: Array[String]): Unit = {
val a = Array(9.12, 9.25, 8.87, 9.99, 6.99, 7.88)
val b = Array(9.15, 9.26, 8.97, 9.89, 6.97, 7.89)
//val compute = setStrategy(strategyOne)
val compute = setStrategy(strategyTwo)
println(compute(a))
println(compute(b))
}
}
在上面的例子中定义了两种求平均值的算法strategyOne和strategyTwo相当于策略模式中的ConcreteStrategy,而setStrategy函数相当于Context。
此模式的重点在于setStrategy函数,它的参数是函数类型,返回值也是一个函数,所以setStrategy函数就可以根据不同的输入算法得到统一的计算函数,如本例中的val compute = setStrategy(strategyTwo)
,从而实现了面向对象编程中策略模式的功能。
网友评论