我正在用不可變對象建模我們的域。用不可變對象模擬繼承+可變狀態
可變的設計
一個基本特徵WObject(世界對象)以及實施像OwnedObj具體操作特性的負載(馬力/老闆/ takeDamage),動產(movementLeft /的moveTo),戰士(攻擊/攻擊)。
在層次結束時,你有一個可變類混合在適當的特質:
class Corvette(var position: Vect2) extends WObject with OwnedObj with Movable with Fighter
如果用戶想要做的操作(可以說移動的船舶除外),你這樣做:
val opt = objects.collectFirst { case obj: Movable if obj.position == position => obj }
opt.fold(Log.error(s"Movable at $position not found!")) { obj =>
obj.moveTo(position) // return type is Unit
}
永恆設計
如果的moveTo必須返回一個新的OBJ等等,它返回什麼類型?
我試過使用trait Movable[Self <: Movable[Self]]
的方法,但是這需要把Movable [_]帶到任何地方,這些存在類型很快就會失去控制。如果我想要Movable[_] with Fighter[_]
?是_同一類型嗎?
我也試圖與類型界限的做法性狀裏面抽象類型自我,但這種開始於以下情況下會很麻煩:
def takeDamage(obj: OwnedObj): obj.Self = if (Random.nextDouble()) obj.takeDamage else obj.self
鳥巢這一點,你會得到類型,如
def attackReachable(
data: WObject.WorldObjUpdate[Self]
): WObject.WorldObjUpdate[data.value._2.Self]
哪些只是可怕的。
我在考慮繼承和使用composition + typeclasses,但我不太確定如何去做。
例如:
case class WObject(position: Vect2, id: UUID=UUID.randomUUID())
case class OwnedObj(owner: Owner)
case class Movable(movementLeft: Int)
case class Fighter(attacked: Boolean)
case class Corvette(obj: WObject, owned: OwnedObj, movable: Movable, fighter: Fighter)
// Something that has both WObject and Movable
trait MovableOps[A <: ???] {
def moveTo(obj: A, target: Vect2): A
}
然後在類型類,這將在伴隨克爾維特對象來實現限定的操作。
但我不知道如何指定約束。
更多關於如何從客戶端實現移動操作?
val opt = objects.collectFirst { case obj: ??? if obj.position == position => obj }
opt.fold(Log.error(s"Movable at $position not found!")) { obj =>
objects = objects - obj + obj.moveTo(position)
}
幫助讚賞:)
相關:(Movable[T] with Fighter[T] forSome {type T})
:Polymorphic updates in an immutable class hierarchy
attackReachable可以做2件事:1)如果目標不能被攻擊,它應該返回'data'。 2)如果可以達到目標,它應該返回更新的數據,其中目標將被改變,Self將被改變並且將其標記爲受到攻擊。由於自我類型1變得不可能,因爲編譯器不知道Self == data.value._2.Self(它是從Self的修改返回的) – arturaz 2014-09-30 11:35:53
也可以詳細說明Monocle vs Shapeless鏡頭嗎? – arturaz 2014-09-30 11:50:37
如果你只有一個不同類型的列表(讓我們說一個WorldObject的基類型),你又怎麼調用moveTo?你是否需要模式匹配到類型類型的類型才能踢入? – arturaz 2014-09-30 12:09:29