Strategy é um dos padrões mais legais na minha opinião, juntamente com Template Method, Command, Observer, entre outros.
Com Scala dá pra implementar o Strategy com pelo menos duas maneiras diferentes: O comum, extendendo um Trait com a interface da estratégia/algoritmo, ou então utilizando o objeto método como sendo um algoritmo. Já que em Scala (assim como em outras linguagens inteiramente OO) o método é um objeto, isto é, podemos chamar métodos de um método, podemos passar métodos como parâmetros, etc, não há a necessidade de encapsularmos um algoritmo dentro de uma classe.
Segue as duas versões:
Encapsulando o algoritmo em objetos:
Strategy.scala
package scala.behavioral
// Strategy = Policy
// Encapsular um algoritmo para que ele possa ser alterado dinamicamente
// Abstract Implementation
trait Strategy {
def run() { // Template method for legibility
algorithm()
}
def algorithm()
}
// Concrete Implementation
class DefaulStrategy extends Strategy {
override def algorithm() {
println("default algorithm")
}
}
class StrategyA extends Strategy {
override def algorithm() {
println("solved using algorithm A")
}
}
class StrategyB extends Strategy {
override def algorithm() {
println("solved using algorithm B")
}
}
class MyApplication(var strategy:Strategy) {
def doSomething() {
strategy.run()
}
}
// Client
object StrategyClient extends Application {
var arg = "a"
var strategy:Strategy = _
arg match {
case "a" => strategy = new StrategyA()
case "b" => strategy = new StrategyB()
case _ => strategy = new DefaulStrategy()
}
var myapp = new MyApplication(strategy)
myapp.doSomething()
myapp.strategy = new StrategyB()
myapp.doSomething()
}
Utilizando o próprio objeto método:
Strategy2.scala
package scala.behavioral
// Strategy = Policy
// Encapsular um algoritmo para que ele possa ser alterado dinamicamente
// Example with function-objects
// Concrete Implementation
class SomeParam
class SomeReturnValue
object Strategies {
def strategyA(param:SomeParam) : SomeReturnValue = {
println("strategy A")
return new SomeReturnValue()
}
def strategyB(param:SomeParam) : SomeReturnValue = {
println("strategy B")
return new SomeReturnValue()
}
def strategyC(param:SomeParam) : SomeReturnValue = {
println("strategy C")
return new SomeReturnValue()
}
}
class MyApplication2(var strategy: (SomeParam => SomeReturnValue)) {
def doSomething(param:SomeParam) : SomeReturnValue = {
return strategy(param)
}
}
// Client
object StrategyClient2 extends Application {
var arg = "a"
var strategy:(SomeParam => SomeReturnValue) = _
arg match {
case "a" => strategy = Strategies.strategyA
case "b" => strategy = Strategies.strategyB
case _ => strategy = Strategies.strategyC
}
var myapp = new MyApplication2(strategy)
myapp.doSomething(new SomeParam())
myapp.strategy = Strategies.strategyC
myapp.doSomething(new SomeParam())
}
Nenhum comentário:
Postar um comentário