ScalaでChain of Responsibility
久しぶりにデザインパターンを読んだので、Scalaで気になったパターンを書いてみました。
自分用のメモです。
Java言語で学ぶデザインパターン入門をそのままScalaにした版
Javaで書かれていたものをScalaにすると多分こんな感じ。
var
を使わないように書いたのでJavaそのままではないけれども..
case class Trouble(no: Int)
trait Support {
val name: String
val next: Option[Support]
def resolve(trouble: Trouble): Boolean
def done(trouble: Trouble): Unit = println(s"$trouble is resolved by $name.")
def fail(trouble: Trouble): Unit = println(s"$trouble cannot be resolved.")
def support(trouble: Trouble): Unit =
if (resolve(trouble)) done(trouble)
else if (next.isDefined) next.get.support(trouble)
else fail(trouble)
}
case class NoSupport(name: String, next: Option[Support] = None) extends Support {
override def resolve(trouble: Trouble): Boolean = false
}
case class LimitSupport(name: String, limit: Int, next: Option[Support] = None) extends Support {
override def resolve(trouble: Trouble): Boolean = trouble.no < limit
}
case class OddSupport(name: String, next: Option[Support] = None) extends Support {
override def resolve(trouble: Trouble): Boolean = trouble.no % 2 == 1
}
case class SpecialSupport(name: String, number: Int, next: Option[Support] = None) extends Support {
override def resolve(trouble: Trouble): Boolean = trouble.no == number
}
val fred = LimitSupport("Fred", 300, None)
val elmo = OddSupport("Elmo", Some(fred))
val diana = LimitSupport("Diana", 200, Some(elmo))
val charlie = SpecialSupport("Charlie", 429, Some(diana))
val bob = LimitSupport("Bob", 100, Some(charlie))
val alice = NoSupport("Alice", Some(bob))
(0 until 500 by 33).foreach(i => alice.support(Trouble(i)))
Trouble(0) is resolved by Bob.
Trouble(33) is resolved by Bob.
Trouble(66) is resolved by Bob.
Trouble(99) is resolved by Bob.
Trouble(132) is resolved by Diana.
Trouble(165) is resolved by Diana.
Trouble(198) is resolved by Diana.
Trouble(231) is resolved by Elmo.
Trouble(264) is resolved by Fred.
Trouble(297) is resolved by Elmo.
Trouble(330) cannot be resolved.
Trouble(363) is resolved by Elmo.
Trouble(396) cannot be resolved.
Trouble(429) is resolved by Charlie.
Trouble(462) cannot be resolved.
Trouble(495) is resolved by Elmo.
Partial Functionで書いてみた版
多分こんな感じにすればいいのかな..
def limitSupportPF(name: String, limit: Int): PartialFunction[Trouble, Unit] = {
case Trouble(no) if no < limit =>
done(name, Trouble(no))
}
def oddSupportPF(name: String): PartialFunction[Trouble, Unit] = {
case Trouble(no) if no % 2 == 1 =>
done(name, Trouble(no))
}
def specialSupportPF(name: String, limit: Int): PartialFunction[Trouble, Unit] = {
case Trouble(no) if no == limit =>
done(name, Trouble(no))
}
def noSupportPF: PartialFunction[Trouble, Unit] = {
case Trouble(no) => fail(Trouble(no))
}
private def done(name: String, trouble: Trouble) = println(s"$trouble is resolved by $name.")
private def fail(trouble: Trouble) = println(s"trouble cannot be rsolved.")
val fredPF = limitSupportPF("Fred", 300)
val elmoPF = oddSupportPF("Elmo")
val dianaPF = limitSupportPF("Diana", 200)
val charliePF = specialSupportPF("Charlie", 429)
val bobPF = limitSupportPF("Bob", 100)
val alicePF = noSupportPF
val pf = bobPF orElse charliePF orElse dianaPF orElse elmoPF orElse fredPF orElse alicePF
(0 until 500 by 33).foreach(no => pf(Trouble(no)))
Author And Source
この問題について(ScalaでChain of Responsibility), 我々は、より多くの情報をここで見つけました https://qiita.com/chocomintkusoyaro/items/a7dbd17b50c61843cbaa著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Content is automatically searched and collected through network algorithms . If there is a violation . Please contact us . We will adjust (correct author information ,or delete content ) as soon as possible .