我想根據具體類可能具有的各種屬性,從特徵中組裝域對象。當我的對象是可變的時,這是非常簡單的。例如:不變的類層次結構中的多態更新
trait HasHitPoints { var hitPoints: Int = 100 }
trait HasBearing { var bearing: Double = 0 }
class Ship extends HasHitPoints with HasBearing
class Base extends HasHitPoints
val entities = new Ship :: new Base :: Nil
entities.collect { case h: HasHitPoints => h.hitPoints += 10 }
特別地,我可以多晶型讀或不知道具體類型更新任何HasHitPoints
實例。
什麼是最好的方式來實現這與不可變對象?如果我很高興剛纔讀的屬性,然後我可以這樣做:
trait HasHitPoints { val hitPoints: Int }
trait HasBearing { val bearing: Double }
case class Ship(hitPoints: Int, bearing: Double) extends HasHitPoints with HasBearing
case class Base(hitPoints: Int) extends HasHitPoints
val things = Ship(50, 0) :: Base(100) :: Nil
val totalHitPoints = things.collect { case h: HasHitPoints => h.hitPoints }.sum
而且,我可以很容易地修改使用copy
具體的類,如果我知道確切類型。例如,困難的部分是更新任意的HasHitPoints
。如果我有很多具體的類和許多不同的屬性,我可能喜歡混入,那麼避免模板代碼爆炸的最佳方案是什麼?
沒錯,儘管N個更新方法在M個具體類中的混亂是我希望避免的。正如你指出的那樣,在動態語言中它會非常簡單。這個用例顯然非常簡單,但我認爲當你將更新與不可變的繼承層次結構混合在一起時,這個問題經常會出現。 – 2012-01-10 13:17:29
我不會爭辯說這是Scala處理不好的問題,但根據我的經驗,這是一種不會經常出現的情況 - 除非您在建模的這段時間已經死了。 – 2012-01-11 13:32:25
可能,雖然我不知道薩皮爾 - 沃爾夫事件的程度如何:語言無法很好地處理的場景會變成不經常出現的場景...... – 2012-01-11 14:28:58