The strategy pattern is used to create an interchangeable family of algorithms from which the required process is chosen at run-time.
Example 1:
// Step 3: Client usage:
fun main(args: Array<String>) {
val add = ArithmeticOperation(addOperation)
val subtract = ArithmeticOperation(subOperation)
val times = ArithmeticOperation(timesOperation)
println("5 + 10 = ${add.calculate(5, 10)}")
println("5 - 10 = ${subtract.calculate(5, 10)}")
println("5 * 10 = ${times.calculate(5, 10)}")
}
// Step 1: Create a strategy class
class ArithmeticOperation(val operation: (Int, Int) -> Int){
fun calculate(x: Int, y: Int): Int{
return operation.invoke(x, y)
}
}
// Step 2: Define some different behaviors:
val addOperation: (Int, Int) -> Int = {x: Int, y: Int -> x+y}
val subOperation = {x: Int, y: Int -> x-y}
val timesOperation = {x: Int, y: Int -> x*y}
/*
prints
5 + 10 = 15
5 - 10 = -5
5 * 10 = 50
*/
Example 2
// Step 4: Client usage:
fun main(args: Array<String>) {
val byAir = GoodsTrans(ByAir())
byAir.execute("Crabs from Australia are transported")
val byWater = GoodsTrans(ByWater())
byWater.execute("Petroleum from Arab is transported")
val byTrain = GoodsTrans(ByTrain())
byTrain.execute("Visitors from Shanghai are transported")
}
// Step 1: Create an strategy interface
interface Strategy{
fun vehicle()
}
// Step 2: Implement the Strategy for different strategies
class ByAir: Strategy{
override fun vehicle() {
println(" by air.")
}
}
class ByTrain: Strategy{
override fun vehicle() {
println(" by train.")
}
}
class ByWater: Strategy{
override fun vehicle() {
println(" by water.")
}
}
// Step 3: Create a context class which use Strategies
class GoodsTrans(val strategy: Strategy){
fun execute(msg: String){
print(msg)
strategy.vehicle()
}
}
/*
prints:
Crabs from Australia are transported by air.
Petroleum from Arab is transported by water.
Visitors from Shanghai are transported by train.
*/