Wikipedia にある 23 のデザインパターン(デザインパターン (ソフトウェア) - Wikipedia)の Java のサンプルを Scala で書いてみる第 2 弾。
今回は、クラスの選択の決定をサブクラスに委ねる実装パターン。 GoF による 23 のデザインパターンでは、Factory Method パターンと呼ばれているもの。
上記 Wikipedia に Java での実装例があるが、これを Scala で実装してみる。
Factory Method パターンの登場人物は、
- Creator
ConcreteCreator - Product
ConcreteProduct
となる。
// FactoryMethod Pattern
// Creator
abstract class ListPrinter {
def printList(list: List[String]) {
val comparator = createComparator
list.sortWith(comparator).foreach(println)
}
// factoryMethod
protected def createComparator: (String, String) => Boolean
}
// Function2[String, String, Boolean] が product に相当
// ConcreteCreator
class DictionaryOrderListPrinter extends ListPrinter {
override protected def createComparator: (String, String) => Boolean =
(s1, s2) => s1 < s2 // ConcreteProduct
}
// ConcreteCreator
class LengthOrderListPrintter extends ListPrinter {
override protected def createComparator: (String, String) => Boolean =
(s1, s2) => s1.size < s2.size // ConcreteProduct
}
object FactoryMethodPatternExampleWiki {
def main(args: Array[String]) = {
val strs = List("いちご", "もも", "いちじく")
println("五十音順で表示:")
(new DictionaryOrderListPrinter).printList(strs)
println("長さ順で表示:")
(new LengthOrderListPrintter).printList(strs)
}
}
実行結果は以下の通り。
[info] Running FactoryMethodPatternExampleWiki
五十音順で表示:
いちご
いちじく
もも
長さ順で表示:
もも
いちご
いちじく
ちょっと無理やり感があって、何ともしっくりこない。。例示のサンプルがあまりよくないのかな・・・
上記の取り上げられている例への解法であれば、Factory Method パターンより、Strategy パターンの方がしっくりくる。
// Strategy Pattern
class ListPrinter(comparator: (String, String) => Boolean) {
def printList(list: List[String]) {
list.sortWith(comparator).foreach(println)
}
}
object StrategyPatternExampleWiki {
def main(args: Array[String]) = {
val strs = List("いちご", "もも", "いちじく")
println("五十音順で表示:")
(new ListPrinter((s1, s2) => s1 < s2)).printList(strs)
println("長さ順で表示:")
(new ListPrinter((s1, s2) => s1.size < s2.size)).printList(strs)
}
}
実行結果は以下の通り。
[info] Running StrategyPatternExampleWiki
五十音順で表示:
いちご
いちじく
もも
長さ順で表示:
もも
いちご
いちじく