作为一个思考练习,我想象了一个简单的游戏,在游戏中Mario类型的角色可以在敌人射击他的情况下奔跑和跳跃...
然后我试图想象使用不可变对象来编写这个游戏。
这引起了我一些困惑(我是一名命令式面向对象的程序员)。
1) 如果我的小家伙在位置x10,y100向右移动1个单位,我是否只需使用旧值重新实例化他,并将其x位置加1(例如x11,y100)?
2) (如果我的第一个假设是正确的) 如果我的输入线程将小家伙向右移动1个单位,而我的敌人AI线程射击小家伙并且敌人AI线程在输入线程之前解决,则我的家伙将失去健康,然后在输入线程解决时,恢复健康并向右移动...
这是否意味着即使具有不可变性,我也不能快速启动线程? 当两个线程操作完成时,我需要同步地发送我的线程以执行它们的工作,然后再进行new()up小家伙吗?还是有一个简单的“功能性”解决方案?
这是一个与我日常工作中面临的稍微不同的线程问题。 通常,我必须决定我是否关心线程解决的顺序。而在上述情况下,我技术上并不关心他先受到伤害还是先移动。但是,如果实例化期间的竞争条件导致一个线程的数据完全丢失,则我确实关心。
3) (再次,如果我的第一个假设是正确的)不断地实例化对象的新实例(例如Mario小家伙)是否具有可怕的开销,使其成为非常严重/重要的设计决策?
编辑 抱歉,因为我不知道这里关于后续问题的良好做法...
4) 如果不可变性是我应该追求并且即使跳跃经过改变也要实例化对象的新版本...如果我每次移动时都实例化我的小家伙(仅具有不同的位置),那么我难道不会遇到与可变性相同的问题吗?因为某些在某个时间点引用他的东西实际上正在查看旧值?..我挖得越深,我的头越晕,因为生成具有不同值的相同事物的新版本似乎就像通过黑客进行可变性。
我的问题是:这应该如何工作?它如何有益于仅突变他的位置?
for(ever)//simplified game-loop update or "tick" method
{
if(Keyboard.IsDown(Key.Right)
guy = new Guy(guy){location = new Point(guy.Location.x +1, guy.Location.y)};
}
以下代码意味着该对象是可变的!(即使它的属性不是)
4.5) 完全不可变的对象是否可能实现这一点?
谢谢,
J.