Mostrando postagens com marcador design patterns. Mostrar todas as postagens
Mostrando postagens com marcador design patterns. Mostrar todas as postagens

segunda-feira, 6 de setembro de 2010

Python Decorator para imprimir o desempenho de um método

Decorators do Python são bem legais, né? É uma solução elegante, simples e 100% OO. Olha um decorator que fiz para imprimir o desempenho de um método (sugestões são sempre bemvindas):


Exemplo de uso:
@print_performance def minha_funcao(): pass
Implementação:
try: from functools import wraps except ImportError: # Python 2.3, 2.4 fallback. from django.utils.functional import wraps import time def print_performance(function): def wrapped_function(*args, **kwargs): print('START %s(%s)' % (function.__name__, args,)) start_time = time.clock() exception = None try: result = function(*args, **kwargs) except Exception, e: exception = e end_time = time.clock() if exception: print('END-ERROR %s(%s): %ss' % (function.__name__, args, str(end_time - start_time))) raise exception print('END %s(%s): %ss' % (function.__name__, args, str(end_time - start_time))) return result return wraps(function)(wrapped_function)

sábado, 28 de agosto de 2010

Design Patterns em Scala: Command

Command: Command.scala package scala.behavioral import scala.collection.jcl.ArrayList // Generic/Abstract objects trait Command[V] { val parameters = new ArrayList[Any]() // throw an exception if invalid parameters def validate() {} def execute() : V def addParameters(params:Any*) { this.parameters ++ params } } trait SimpleCommand extends Command[Any] { def execute() : Any } // Composite trait CompoundCommand[V] extends Command[ArrayList[V]] { val commands = new ArrayList[Command[V]]() override def validate() { for(command <- commands) command.validate() } override def execute() : ArrayList[V] = { var result = new ArrayList[V]() for(command <- commands) result.add(command.execute()) return result } } trait SimpleCompoundCommand extends CompoundCommand[Any] // Concrete objects case class MyValue(val str:String) class SomeConcreteCommand extends Command[MyValue] { override def execute() : MyValue = { print("Hello ") return new MyValue("SomeConcreteCommand") } } class AnotherConcreteCommand extends Command[MyValue] { override def execute() : MyValue = { println("Command!") return new MyValue("AnotherConcreteCommand") } } class ComplexConcreteCommand extends CompoundCommand[MyValue] { commands.add(new SomeConcreteCommand()) commands.add(new AnotherConcreteCommand()) } object CommandClient extends Application { var c1 = new SomeConcreteCommand() var c2 = new AnotherConcreteCommand() var c3 = new ComplexConcreteCommand() c1.execute() c2.execute() c3.execute() }

Design Patterns em Scala: Singleton

Singleton: Em Scala o padrão Singleton está embutido na linguagem e substitui os temíveis métodos static de Java que são um pesadelo para testes de unidade. O Singleton, criado com a palavra reservada object agrega os métodos de classe, isto é, que não depende dos dados de uma instância. Veja o exemplo abaixo: Singleton.scala package scala.creational // Permitir a criação de uma só instância de um tipo de objeto object Singleton { // object in scala is a singleton class var value:Int = _ def someMethod() : String = { "Hello Singleton!" } } // Error: //class BadSingleton private () { // private var instance:BadSingleton = null // // def getInstance() : BadSingleton = { // if(instance == null) instance = new DummySingleton() // return instance // } //} // Client object SingletonClient extends Application { println(Singleton.someMethod()) // Compile error // var s = new Singleton() var s1 = Singleton var s2 = Singleton println(Singleton.value) s1.value = 1 println(Singleton.value) s2.value = 2 println(Singleton.value) println(s1 == s2) // Compile error // println(new BadSingleton().getInstance()) // println(BadSingleton.getInstance()) }

Design Patterns em Scala: Composite

Composite: Composite.scala package scala.structural import scala.collection.jcl.ArrayList // Permite tratar uma requisição a uma composição de componentes da mesma forma a um único componente class SomeObject { def someTask() {} } class Composite extends SomeObject { var objects = new ArrayList[SomeObject]() override def someTask() { for(o <- objects) o.someTask() } } // Client object CompositeClient extends Application { var someObject1 = new SomeObject() var someObject2 = new Composite() someObject1.someTask() someObject2.someTask() }

Design Patterns em Scala: Template Method

O padrão TemplateMethod é muito legal, essencial principalmente para quando vamos implementar frameworks ou engines. Vale a pena conhecer também! Segue o arquivo:

TemplateMethod.scala

  package scala.behavioral // Define o esqueleto de um algoritmo e delega a implementação de alguns passos às sub-classes // Abstract Implementation abstract class SomeFramework { def templateMethod() { // some implementation here someAbstractMethod() // some implementation here } def someAbstractMethod() } // Concrete Implementation class MyFramework extends ClassWithTemplateMethod { override def someAbstractMethod() { println("partial implementation of the framework") } } // Client object TemplateMethodClient extends Application { var framework = new MyFramework() framework.templateMethod() }

Design Patterns em Scala: Observer

Observer é um padrão muito legal, principalmente quando vamos trabalhar com a arquitetura MVC ou parecidas. O padrão MVC 'original' utiliza o padrão observer, mas como só falamos em Web, e os frameworks Web fornecem uma arquitetura MVC sem o observer (sem um Push no client), então vamos esquecendo... Dá para pensar no Observer para Web por exemplo com o framework Comet para Java, consequentemente para Scala. Segue uma implementação: Observer.scala package scala.behavioral import scala.collection.jcl.ArrayList // Observer = Publisher-Subscriber // Dependência 1-N onde os N dependentes serão notificados e atualizos a cada mudança de estado do objeto que está sendo observado // Abstract implementation trait Observable { // Publisher val observers = new ArrayList[Observer]() def notifyObservers() { for(observer <- observers) observer.notification() } def addObserver(observer:Observer) { observers += observer } def removeObserver(observer:Observer) { observers -= observer } } trait Observer { // Subscriber def notification() } // Concrete Implementation class SomeObservable extends Observable class SomeObserver extends Observer { override def notification() { println("do something here: SomeObserver") } } class AnotherObserver extends Observer { override def notification() { println("do something here: AnotherObserver") } } // Client object ObserverClient extends Application { var observable = new SomeObservable() var observer1 = new SomeObserver() var observer2 = new AnotherObserver() observable.addObserver(observer1) observable.addObserver(observer2) observable.notifyObservers() observable.removeObserver(observer2) observable.notifyObservers() }

Design Patterns em Scala: Facade

Facade: Facade.scala package scala.structural // Facilita o uso de um sistema unificando o comportamento de diversos objetos // Concrete Implementation trait SubSystemA {  def methodA1()  def methodA2() } trait SubSystemB {  def methodB() } class ConcreteSubSystemA extends SubSystemA {  override def methodA1() {   println("System A")  }  override def methodA2() {   println("System A")  } } class ConcreteSubSystemB extends SubSystemB {  override def methodB() {   println("System B")  } } class Facade extends SubSystemA with SubSystemB {  val subsystemA = new ConcreteSubSystemA()  val subsystemB = new ConcreteSubSystemB()  override def methodA1() {   subsystemA.methodA1()  }  override def methodA2() {   subsystemA.methodA2()  }  override def methodB() {   subsystemB.methodB()  } } // Client object FacadeClient extends Application {  var facade = new Facade()  facade.methodA1()  facade.methodA2()  facade.methodB() }

Design Patterns em Scala: State

Segue mais dois padrões de projeto em Scala: State: State.scala package scala.behavioral // Mudar o comportamento mude de acordo com seu estado // Abstract Implementation class Context { var state:State = _ state = new NullState() def handle() { state.handle() } } trait State { def handle() } // Concrete Implementation class NullState extends State { override def handle() { println("blank algorithm, maybe throw an exception of unitilized context") } } class StateA extends State { override def handle() { println("algorithm for state A") } } class StateB extends State { override def handle() { println("algorithm for state B") } } // Client object StateClient extends Application { var context = new Context() context.state = new StateA() context.handle() context.state = new StateB() context.handle() }

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.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()) }

Design Patterns em Scala: Chain of Responsibility

Design Patterns são fundamentais para um bom design O.O., para quem não conhece, existem diversos livros excelentes sobre o assunto, por exemplo: GoF e em Java

Abaixo segue alguns padrões em Scala:

Chain of Responsability:

ChainOfResponsability.scala
package scala.behavioral import scala.collection.jcl.ArrayList abstract class HandlerResponsability[D,V]() { var responsable = false def isResponsable():Boolean = responsable def execute(data:D) : V } // Composite style class ChainOfResponsability[D,V] extends HandlerResponsability[D, V] { this.responsable = true val handlers = new ArrayList[HandlerResponsability[D,V]]() override def execute(data:D) : V = { for(handler <- handlers) { var value = handler.execute(data) if(handler.isResponsable()) return value } throw new RuntimeException("Throw unsolved or return a default value") } def addHandler(handler:HandlerResponsability[D,V]) { handlers += handler } } class MyData(val value:Int) class MyResult(val str:String) { override def toString():String = str } class SomeConcreteHandler extends HandlerResponsability[MyData, MyResult] { override def execute(data:MyData) : MyResult = { // set true or false, depends on the data println("Running SomeConcreteHandler") if(data.value == 5) { this.responsable = true return new MyResult("result from SomeConcreteHandler") } return null } } class AnotherConcreteHandler extends HandlerResponsability[MyData, MyResult] { override def execute(data:MyData) : MyResult = { println("Running AnotherConcreteHandler") // set true or false, depends on the data if(data.value == 3) { this.responsable = true return new MyResult("result from AnotherConcreteHandler") } return null } } // Composite style class MyChainOfResponsability extends ChainOfResponsability[MyData, MyResult] { super.addHandler(new SomeConcreteHandler()) super.addHandler(new AnotherConcreteHandler()) } object ChainOfResponsabilityClient extends Application { var handler = new MyChainOfResponsability() println(handler.execute(new MyData(3))) println(handler.execute(new MyData(5))) }