Scalaでデザインパターン(Abstract factory) (Wikipedia実装)
ScalaでAbstract factoryパターンを実装してみた(Wikipedia実装)
WikipediaのAbstract factoryパターンを実装
JavaのサンプルはreadFromConfigFileメソッドが定義されていないため、Pythonのサンプルを参考に引数渡しに変更した
/* GUIFactory example -- */
trait GUIFactory {
def createButton():Button
}
class WinFactory extends GUIFactory {
def createButton():Button = new WinButton()
}
class OSXFactory extends GUIFactory {
def createButton():Button = new OSXButton()
}
trait Button {
def paint()
}
class WinButton extends Button {
def paint() = println("I'm a WinButton")
}
class OSXButton extends Button {
def paint() = println("I'm an OSXButton")
}
class Application(factory:GUIFactory) {
var button:Button = factory.createButton()
button.paint()
}
object ApplicationRunner {
def main(args: Array[String]) {
new Application(createOsSpecificFactory(args(0)))
}
def createOsSpecificFactory(sys:String):GUIFactory = {
sys match {
case "windows" => return new WinFactory()
case "linux" => return new WinFactory()
}
}
}
Scalaでデザインパターン(Flyweight) (Wikipedia実装)
ScalaでFlyweightパターンを実装してみた(Wikipedia実装)
import scala.collection.mutable.ArrayBuffer
class Stamp(t:Char) {
val _type = t
def print() = System.out.print(_type)
}
class StampFactory {
var pool = Map[Char, Stamp]()
def get(t:Char):Stamp = {
this.pool.get(t) match {
case Some(s:Stamp) => return s
case None => val stamp = new Stamp(t)
this.pool += t -> stamp
return stamp
}
}
}
val factory = new StampFactory()
var stamps = new ArrayBuffer[Stamp]()
stamps += factory.get('\u305f')
stamps += factory.get('\u304b')
stamps += factory.get('\u3044')
stamps += factory.get('\u305f')
stamps += factory.get('\u3051')
stamps += factory.get('\u305f')
stamps += factory.get('\u3066')
stamps += factory.get('\u304b')
stamps += factory.get('\u3051')
stamps += factory.get('\u305f')
stamps.foreach { s => s.print() }
ScalaでJavaのObservableクラスを実装してみた
ScalaでJavaのObservableクラスを実装してみた
JavaのObservableクラスは継承する必要があって使いにくいので、scalaでmix-in対応してみました
メソッド名はscalaっぽく変更してあります
Observer([T]の箇所)については特に規定していません
import scala.collection.mutable.SynchronizedSet
import scala.collection.mutable.LinkedHashSet
trait Observable[T]{
private var observers = new LinkedHashSet[T]() with SynchronizedSet[T]
var hasChanged:Boolean = false
protected def clearChanged() = hasChanged = false
def +(observer:T) = observers + observer
def -(observer:T) = if (size() > 0) observers - observer
def size():Int = observers.size
def clear() = observers.clear
def setChanged() = hasChanged = true
def notifyObservers(f:(T)=>Unit) = {
if (hasChanged) observers.foreach { f(_) }
clearChanged()
}
}
※こちらのサイトを参考にさせて頂きました。ありがとうございました
使用例
こちらのサイトのObserverパターン実装例を使用させて頂きました
import scala.collection.mutable.ArrayBuffer
trait Observer {
def update(o:Observable[Observer])
}
class IntegerDataBag extends Observable[Observer] {
private val list = new ArrayBuffer[Int]()
def notifyObservers(o:Observable[Observer]) {
setChanged()
super.notifyObservers(_.update(o))
}
def add(i:Int) {
list += i
notifyObservers(this)
}
def toList():List[Int] = list.toList
def remove(index:Int):Int = {
if (index < list.size) {
val i = list.remove(index)
notifyObservers(this)
return i
}
return -1
}
}
class IntegerAdder(_bag:IntegerDataBag) extends Observer {
var bag:IntegerDataBag = _bag
bag + this
def update(o:Observable[Observer]) {
if( o == bag ) {
println( "The contents of the IntegerDataBag have changed." )
var counter = 0
bag.toList.foreach { counter += _ }
println( "The new sum of the integers is: " + counter )
}
}
}
class IntegerPrinter(_bag:IntegerDataBag) extends Observer {
var bag:IntegerDataBag = _bag
bag + this
def update(o:Observable[Observer]) {
if( o == bag ) {
println( "The contents of the IntegerDataBag have changed." )
println( "The new contents of the IntegerDataBag contains:" )
bag.toList.foreach { println(_) }
}
}
}
object Driver {
def main(args: Array[String]): Unit = {
val i1 = 1;val i2 = 2
val i3 = 3;val i4 = 4
val i5 = 5;val i6 = 6
val i7 = 7;val i8 = 8
val i9 = 9
var bag = new IntegerDataBag()
bag.add( i1 ); bag.add( i2 ); bag.add( i3 ); bag.add( i4 )
bag.add( i5 ); bag.add( i6 ); bag.add( i7 ); bag.add( i8 )
var adder = new IntegerAdder( bag )
var printer = new IntegerPrinter( bag )
// adder and printer add themselves to the bag
println( "About to add another integer to the bag:" )
bag.add( i9 )
println("")
println("About to remove an integer from the bag:")
bag.remove( 0 )
}
}
Scalaでデザインパターン(Interpreter) (Wikipedia実装)
ScalaでInterpreterパターンを実装してみた(Wikipedia実装)
import scala.util.parsing.combinator._
import scala.collection.mutable.Stack
abstract case class Expression() {
def interpret(s:Stack[Int])
}
case class Number(number:Int) extends Expression{
override def interpret(s:Stack[Int]) = {
s.push(number)
}
}
case class Plus() extends Expression{
override def interpret(s:Stack[Int]) = {
s.push( s.pop() + s.pop() )
}
}
case class Minus() extends Expression{
override def interpret(s:Stack[Int]) = {
s.push( - s.pop() + s.pop() )
}
}
object ExpressionParser extends JavaTokenParsers {
var parseTree:List[Expression] = _
def expr:Parser[Unit] = rep(term) ^^ ( e => parseTree = e)
def term:Parser[Expression] =
decimalNumber ^^ ( e => Number(e.toInt) ) |
"+" ^^ ( e => Plus()) |
"-" ^^ ( e => Minus())
def parse(text:String) = {
parseAll(expr, text)
}
def evaluate():Int = {
val context:Stack[Int] = new Stack[Int]();
parseTree.foreach ( e => e.interpret(context) )
return context.pop()
}
}
val expression = "42 4 2 - +";
ExpressionParser.parse(expression)
println("'" + expression +"' equals " + ExpressionParser.evaluate())
パーサーコンビネーターを使って実装してみましたが、なんかもったいない使い方
Scalaでデザインパターン(Strategy) (Wikipedia実装)
ScalaでStrategyパターンを実装してみた(Wikipedia実装)
def ConcreteStrategyA() = println("Called ConcreteStrategyA.execute()")
def ConcreteStrategyB() = println("Called ConcreteStrategyB.execute()")
def ConcreteStrategyC() = println("Called ConcreteStrategyC.execute()")
class Context(f:() => Unit) {
def execute() = f()
}
var context:Context = _
context = new Context(ConcreteStrategyA)
context.execute()
context = new Context(ConcreteStrategyB)
context.execute()
context = new Context(ConcreteStrategyC)
context.execute()



