使用命令模式的时候,我会直接在我的域名解释这一点,因为它会得到纷繁复杂的提高代码的组织......在斯卡拉
在MTG,有可更换的事件,例如获得生命。我想在事件执行之前使用部分函数进行替换。为此,每个事件都需要成为案例类的一个实例。
//a replaceable event
trait Event { def execute(): Unit }
//an effect that replaces an event
type ReplacementEffect = PartialFunction[Event, Event]
//applies all effects to the event. If a replacement doesn't match, the
//event remains unchanged
def replace(event: Event, effects: ReplacementEffect*) =
effects.foldLeft(event) { case (event, effect) => effect.applyOrElse(event, identity[Event] _) }
def executeReplaced(event: Event) = replace(event, activeEffects: _*).execute()
//example: A player's life points
var _life = 20
//one instance of a replaceable event
case class GainLife(life: Int) extends Event {
def execute() = {
// ====== here goes the Interesting Game Logic
_life += life
}
}
def gainLife(life: Int) =
// ====== the place where Interesting Game Logic belongs logically
executeReplaced(GainLife(life))
//execution:
val double: ReplacementEffect = {
//gain twice as much life
case GainLife(x) => GainLife(x * 2)
}
//one effect is active
val activeEffects = List(double)
//gain six life
println(_life)
gainLife(3)
println(_life)
如果我没有接替者的要求,我可以凝结(部分)于以下内容:
//a replaceable event
type Event =() => Unit
//example: A player's life points
//one instance of a replaceable event
def gainLife(life: Int) = executeReplaced {() =>
_life += life
}
我喜欢这个代码更好的是,有趣的游戏逻辑嵌套在它所属的gainLife方法中。 即使在我需要案例班时,是否可以在本地保留这些内容?我能想出这是最好的,但除了本身看笨拙,在GainLife
情况下类是私有的块,所以它只是作为可用作任何情况下,类可言:
executeReplaced {
case class GainLife(life: Int) extends Event {
def execute() = {
_life += life
}
}
GainLife(life)
}
离开我的领域,问题基本上使命令模式看起来很好看:命令的逻辑属于一个地方,我想在那里声明它。但是之后我必须在相同的地方定义命令的参数,并且我努力使它们可用于其他地方的代码。如果我将数据从逻辑中分离出来,除了逻辑所在的位置外,我无法执行任何命令,并且会再次破坏代码的局部性。
这解决了一个问题,但不是我具有一个:我想'生活+ = N'地方用'gainLife'方法,而不是本地与所有其他事件。而且,这组事件并不是我认为“从一开始就知道的”,因此密封并不是这里最好的主意。 – 2015-02-10 09:56:17
对不起,以为你想保持修改逻辑接近状态,不接近事件,我想我误解了你的问题。 – johanandren 2015-02-10 10:22:35