├── .gitignore ├── ChainOfResposibility.scala ├── Command.scala ├── Composite.scala ├── Facade.scala ├── Observer.scala ├── README.md ├── Singleton.scala ├── State.scala ├── Strategy.scala ├── Strategy2.scala └── TemplateMethod.scala /.gitignore: -------------------------------------------------------------------------------- 1 | *.class 2 | *.log 3 | 4 | # sbt specific 5 | dist/* 6 | target/ 7 | lib_managed/ 8 | src_managed/ 9 | project/boot/ 10 | project/plugins/project/ 11 | 12 | # Scala-IDE specific 13 | .scala_dependencies -------------------------------------------------------------------------------- /ChainOfResposibility.scala: -------------------------------------------------------------------------------- 1 | package scala.behavioral 2 | 3 | import scala.collection.jcl.ArrayList 4 | 5 | abstract class HandlerResponsability[D,V]() { 6 | var responsable = false 7 | 8 | def isResponsable():Boolean = responsable 9 | 10 | def execute(data:D) : V 11 | } 12 | 13 | // Composite style 14 | class ChainOfResponsability[D,V] extends HandlerResponsability[D, V] { 15 | this.responsable = true 16 | val handlers = new ArrayList[HandlerResponsability[D,V]]() 17 | 18 | override def execute(data:D) : V = { 19 | for(handler <- handlers) { 20 | var value = handler.execute(data) 21 | if(handler.isResponsable()) 22 | return value 23 | } 24 | throw new RuntimeException("Throw unsolved or return a default value") 25 | } 26 | 27 | def addHandler(handler:HandlerResponsability[D,V]) { 28 | handlers += handler 29 | } 30 | } 31 | 32 | class MyData(val value:Int) 33 | 34 | class MyResult(val str:String) { 35 | override def toString():String = str 36 | } 37 | 38 | class SomeConcreteHandler extends HandlerResponsability[MyData, MyResult] { 39 | override def execute(data:MyData) : MyResult = { 40 | // set true or false, depends on the data 41 | println("Running SomeConcreteHandler") 42 | if(data.value == 5) { 43 | this.responsable = true 44 | return new MyResult("result from SomeConcreteHandler") 45 | } 46 | return null 47 | } 48 | } 49 | 50 | class AnotherConcreteHandler extends HandlerResponsability[MyData, MyResult] { 51 | override def execute(data:MyData) : MyResult = { 52 | println("Running AnotherConcreteHandler") 53 | // set true or false, depends on the data 54 | if(data.value == 3) { 55 | this.responsable = true 56 | return new MyResult("result from AnotherConcreteHandler") 57 | } 58 | return null 59 | } 60 | } 61 | 62 | // Composite style 63 | class MyChainOfResponsability extends ChainOfResponsability[MyData, MyResult] { 64 | super.addHandler(new SomeConcreteHandler()) 65 | super.addHandler(new AnotherConcreteHandler()) 66 | } 67 | 68 | object ChainOfResponsabilityClient extends Application { 69 | var handler = new MyChainOfResponsability() 70 | println(handler.execute(new MyData(3))) 71 | println(handler.execute(new MyData(5))) 72 | } -------------------------------------------------------------------------------- /Command.scala: -------------------------------------------------------------------------------- 1 | package scala.behavioral 2 | 3 | import scala.collection.jcl.ArrayList 4 | 5 | // Generic/Abstract objects 6 | 7 | trait Command[V] { 8 | val parameters = new ArrayList[Any]() 9 | 10 | // throw an exception if invalid parameters 11 | def validate() {} 12 | 13 | def execute() : V 14 | 15 | def addParameters(params:Any*) { 16 | this.parameters ++ params 17 | } 18 | } 19 | 20 | trait SimpleCommand extends Command[Any] { 21 | def execute() : Any 22 | } 23 | 24 | // Composite 25 | trait CompoundCommand[V] extends Command[ArrayList[V]] { 26 | val commands = new ArrayList[Command[V]]() 27 | 28 | override def validate() { 29 | for(command <- commands) 30 | command.validate() 31 | } 32 | 33 | override def execute() : ArrayList[V] = { 34 | var result = new ArrayList[V]() 35 | for(command <- commands) 36 | result.add(command.execute()) 37 | return result 38 | } 39 | 40 | } 41 | 42 | trait SimpleCompoundCommand extends CompoundCommand[Any] 43 | 44 | // Concrete objects 45 | 46 | case class MyValue(val str:String) 47 | 48 | class SomeConcreteCommand extends Command[MyValue] { 49 | override def execute() : MyValue = { 50 | print("Hello ") 51 | return new MyValue("SomeConcreteCommand") 52 | } 53 | } 54 | 55 | class AnotherConcreteCommand extends Command[MyValue] { 56 | override def execute() : MyValue = { 57 | println("Command!") 58 | return new MyValue("AnotherConcreteCommand") 59 | } 60 | } 61 | 62 | class ComplexConcreteCommand extends CompoundCommand[MyValue] { 63 | commands.add(new SomeConcreteCommand()) 64 | commands.add(new AnotherConcreteCommand()) 65 | } 66 | 67 | object CommandClient extends Application { 68 | var c1 = new SomeConcreteCommand() 69 | var c2 = new AnotherConcreteCommand() 70 | var c3 = new ComplexConcreteCommand() 71 | c1.execute() 72 | c2.execute() 73 | c3.execute() 74 | } -------------------------------------------------------------------------------- /Composite.scala: -------------------------------------------------------------------------------- 1 | package scala.structural 2 | 3 | import scala.collection.jcl.ArrayList 4 | 5 | // Permite tratar uma requisição a uma composição de componentes da mesma forma a um único componente 6 | 7 | class SomeObject { 8 | def someTask() {} 9 | } 10 | 11 | class Composite extends SomeObject { 12 | var objects = new ArrayList[SomeObject]() 13 | 14 | override def someTask() { 15 | for(o <- objects) 16 | o.someTask() 17 | } 18 | } 19 | 20 | // Client 21 | object CompositeClient extends Application { 22 | var someObject1 = new SomeObject() 23 | var someObject2 = new Composite() 24 | someObject1.someTask() 25 | someObject2.someTask() 26 | } -------------------------------------------------------------------------------- /Facade.scala: -------------------------------------------------------------------------------- 1 | package scala.structural 2 | 3 | // Facilita o uso de um sistema unificando o comportamento de diversos objetos 4 | 5 | // Concrete Implementation 6 | 7 | trait SubSystemA { 8 | def methodA1() 9 | def methodA2() 10 | } 11 | 12 | trait SubSystemB { 13 | def methodB() 14 | } 15 | 16 | class ConcreteSubSystemA extends SubSystemA { 17 | override def methodA1() { 18 | println("System A") 19 | } 20 | 21 | override def methodA2() { 22 | println("System A") 23 | } 24 | } 25 | 26 | class ConcreteSubSystemB extends SubSystemB { 27 | override def methodB() { 28 | println("System B") 29 | } 30 | } 31 | 32 | class Facade extends SubSystemA with SubSystemB { 33 | val subsystemA = new ConcreteSubSystemA() 34 | val subsystemB = new ConcreteSubSystemB() 35 | override def methodA1() { 36 | subsystemA.methodA1() 37 | } 38 | override def methodA2() { 39 | subsystemA.methodA2() 40 | } 41 | override def methodB() { 42 | subsystemB.methodB() 43 | } 44 | } 45 | 46 | // Client 47 | object FacadeClient extends Application { 48 | var facade = new Facade() 49 | facade.methodA1() 50 | facade.methodA2() 51 | facade.methodB() 52 | } -------------------------------------------------------------------------------- /Observer.scala: -------------------------------------------------------------------------------- 1 | package scala.behavioral 2 | 3 | import scala.collection.jcl.ArrayList 4 | 5 | // Observer = Publisher-Subscriber 6 | // 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 7 | 8 | // Abstract implementation 9 | 10 | trait Observable { // Publisher 11 | val observers = new ArrayList[Observer]() 12 | 13 | def notifyObservers() { 14 | for(observer <- observers) 15 | observer.notification() 16 | } 17 | 18 | def addObserver(observer:Observer) { 19 | observers += observer 20 | } 21 | 22 | def removeObserver(observer:Observer) { 23 | observers -= observer 24 | } 25 | } 26 | 27 | trait Observer { // Subscriber 28 | def notification() 29 | } 30 | 31 | // Concrete Implementation 32 | 33 | class SomeObservable extends Observable 34 | 35 | class SomeObserver extends Observer { 36 | override def notification() { 37 | println("do something here: SomeObserver") 38 | } 39 | } 40 | 41 | class AnotherObserver extends Observer { 42 | override def notification() { 43 | println("do something here: AnotherObserver") 44 | } 45 | } 46 | 47 | // Client 48 | 49 | object ObserverClient extends Application { 50 | var observable = new SomeObservable() 51 | var observer1 = new SomeObserver() 52 | var observer2 = new AnotherObserver() 53 | observable.addObserver(observer1) 54 | observable.addObserver(observer2) 55 | observable.notifyObservers() 56 | observable.removeObserver(observer2) 57 | observable.notifyObservers() 58 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | scala-design-patterns 2 | ===================== -------------------------------------------------------------------------------- /Singleton.scala: -------------------------------------------------------------------------------- 1 | package scala.creational 2 | 3 | // Permitir a criação de uma só instância de um tipo de objeto 4 | 5 | 6 | object Singleton { 7 | // object in scala is a singleton class 8 | var value:Int = _ 9 | 10 | def someMethod() : String = { 11 | "Hello Singleton!" 12 | } 13 | } 14 | 15 | // Error: 16 | //class BadSingleton private () { 17 | // private var instance:BadSingleton = null 18 | // 19 | // def getInstance() : BadSingleton = { 20 | // if(instance == null) instance = new DummySingleton() 21 | // return instance 22 | // } 23 | //} 24 | 25 | // Client 26 | 27 | object SingletonClient extends Application { 28 | println(Singleton.someMethod()) 29 | // Compile error 30 | // var s = new Singleton() 31 | var s1 = Singleton 32 | var s2 = Singleton 33 | println(Singleton.value) 34 | s1.value = 1 35 | println(Singleton.value) 36 | s2.value = 2 37 | println(Singleton.value) 38 | println(s1 == s2) 39 | 40 | // Compile error 41 | // println(new BadSingleton().getInstance()) 42 | // println(BadSingleton.getInstance()) 43 | } -------------------------------------------------------------------------------- /State.scala: -------------------------------------------------------------------------------- 1 | package scala.behavioral 2 | 3 | // Mudar o comportamento mude de acordo com seu estado 4 | 5 | // Abstract Implementation 6 | 7 | class Context { 8 | var state:State = _ 9 | state = new NullState() 10 | 11 | def handle() { 12 | state.handle() 13 | } 14 | } 15 | 16 | trait State { 17 | def handle() 18 | } 19 | 20 | // Concrete Implementation 21 | 22 | class NullState extends State { 23 | override def handle() { 24 | println("blank algorithm, maybe throw an exception of unitilized context") 25 | } 26 | } 27 | 28 | class StateA extends State { 29 | override def handle() { 30 | println("algorithm for state A") 31 | } 32 | } 33 | 34 | class StateB extends State { 35 | override def handle() { 36 | println("algorithm for state B") 37 | } 38 | } 39 | 40 | // Client 41 | 42 | object StateClient extends Application { 43 | var context = new Context() 44 | context.state = new StateA() 45 | context.handle() 46 | context.state = new StateB() 47 | context.handle() 48 | } -------------------------------------------------------------------------------- /Strategy.scala: -------------------------------------------------------------------------------- 1 | package scala.behavioral 2 | 3 | // Strategy = Policy 4 | // Encapsular um algoritmo para que ele possa ser alterado dinamicamente 5 | 6 | // Abstract Implementation 7 | trait Strategy { 8 | def run() { // Template method for legibility 9 | algorithm() 10 | } 11 | 12 | def algorithm() 13 | } 14 | 15 | // Concrete Implementation 16 | class DefaulStrategy extends Strategy { 17 | override def algorithm() { 18 | println("default algorithm") 19 | } 20 | } 21 | 22 | class StrategyA extends Strategy { 23 | override def algorithm() { 24 | println("solved using algorithm A") 25 | } 26 | } 27 | 28 | class StrategyB extends Strategy { 29 | override def algorithm() { 30 | println("solved using algorithm B") 31 | } 32 | } 33 | 34 | class MyApplication(var strategy:Strategy) { 35 | def doSomething() { 36 | strategy.run() 37 | } 38 | } 39 | 40 | // Client 41 | object StrategyClient extends Application { 42 | var arg = "a" 43 | var strategy:Strategy = _ 44 | arg match { 45 | case "a" => strategy = new StrategyA() 46 | case "b" => strategy = new StrategyB() 47 | case _ => strategy = new DefaulStrategy() 48 | } 49 | var myapp = new MyApplication(strategy) 50 | myapp.doSomething() 51 | myapp.strategy = new StrategyB() 52 | myapp.doSomething() 53 | } -------------------------------------------------------------------------------- /Strategy2.scala: -------------------------------------------------------------------------------- 1 | package scala.behavioral 2 | // Strategy = Policy 3 | // Encapsular um algoritmo para que ele possa ser alterado dinamicamente 4 | // Example with function-objects 5 | // Concrete Implementation 6 | class SomeParam 7 | class SomeReturnValue 8 | 9 | object Strategies { 10 | def strategyA(param:SomeParam) : SomeReturnValue = { 11 | println("strategy A") 12 | return new SomeReturnValue() 13 | } 14 | 15 | def strategyB(param:SomeParam) : SomeReturnValue = { 16 | println("strategy B") 17 | return new SomeReturnValue() 18 | } 19 | 20 | def strategyC(param:SomeParam) : SomeReturnValue = { 21 | println("strategy C") 22 | return new SomeReturnValue() 23 | } 24 | } 25 | 26 | class MyApplication2(var strategy: (SomeParam => SomeReturnValue)) { 27 | def doSomething(param:SomeParam) : SomeReturnValue = { 28 | return strategy(param) 29 | } 30 | } 31 | 32 | // Client 33 | object StrategyClient2 extends Application { 34 | var arg = "a" 35 | var strategy:(SomeParam => SomeReturnValue) = _ 36 | arg match { 37 | case "a" => strategy = Strategies.strategyA 38 | case "b" => strategy = Strategies.strategyB 39 | case _ => strategy = Strategies.strategyC 40 | } 41 | var myapp = new MyApplication2(strategy) 42 | myapp.doSomething(new SomeParam()) 43 | myapp.strategy = Strategies.strategyC 44 | myapp.doSomething(new SomeParam()) 45 | } -------------------------------------------------------------------------------- /TemplateMethod.scala: -------------------------------------------------------------------------------- 1 | package scala.behavioral 2 | 3 | // Define o esqueleto de um algoritmo e delega a implementação de alguns passos às sub-classes 4 | // Abstract Implementation 5 | abstract class SomeFramework { 6 | def templateMethod() { 7 | // some implementation here 8 | someAbstractMethod() 9 | // some implementation here 10 | } 11 | 12 | def someAbstractMethod() 13 | } 14 | 15 | // Concrete Implementation 16 | class MyFramework extends ClassWithTemplateMethod { 17 | override def someAbstractMethod() { 18 | println("partial implementation of the framework") 19 | } 20 | } 21 | 22 | // Client 23 | object TemplateMethodClient extends Application { 24 | var framework = new MyFramework() 25 | framework.templateMethod() 26 | } --------------------------------------------------------------------------------