Saturday, August 28, 2010

Design Patterns em Scala: Strategy

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.scalapackage scala.behavioral// Strategy = Policy// Encapsular um algoritmo para que ele possa ser alterado dinamicamente// Abstract Implementationtrait Strategy { def run() { // Template method for legibility  algorithm() } def algorithm()}// Concrete Implementationclass 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() }}// Clientobject 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.scalapackage scala.behavioral// Strategy = Policy// Encapsular um algoritmo para que ele possa ser alterado dinamicamente// Example with function-objects// Concrete Implementationclass SomeParamclass SomeReturnValueobject 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) }}// Clientobject 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())}

No comments:

Post a Comment