我在奥尔良为一场比赛的玩家准备了一粒粮食。一个玩家有几个我想在客户端直接访问的属性。这是可能的吗?它是有效的吗?将这些作为公共属性放在谷物上是否有意义?或者,我是否应该使用一个GetAllState方法返回一个DTO,其中包含这些属性的当前值?
public interface IPlayerGrain : IGrainWithIntegerKey
{
// Individual public properties to access grain state?
string Name { get; }
int Score { get; }
int Health { get; }
// Or, get all the current grain state as DTO?
Task<PlayerState> GetAllState();
}根据我目前的理解,我认为我需要使用GetAllState,因为我认为任何进入颗粒的通信都需要通过一种方法,这可能会在竖井之间传递。因此,您可能希望最小化传递的消息数量,而不希望传递三条消息来获取Name、Score和Health。或者,消息传递是不是很便宜,我不应该担心做得太多?在我的例子中我只包含了3个属性,但在我的真实游戏中会有更多的属性。
然而,我真的不喜欢让一个贫乏的DTO模型仅仅是颗粒内部属性的副本。
所以我想知道在奥尔良有没有更好的方式,或者更好的模式?
发布于 2021-11-19 14:30:09
我认为这在很大程度上取决于属性的生命周期和访问模式。这些属性倾向于独立更改还是一起更改?(乍一看,它们似乎是以完全不同的速率独立更改的;我假设Score和Health可以非常频繁地更改,但名称几乎永远不会更改。)考虑到这个名称很少更改,那么当您想要更新得分或Health值时,它是否适合您的访问模式检索它?也许Score和Health会经常一起访问,Name和其他更静态的属性也属于一起。
如果您在考虑消息传递的成本之前就让这些类型的问题驱动您的API,那么您可能会找到一些很好的关键点(可能不是整个状态)。您还可以考虑拥有一个播放器粒度和一个PlayerStats粒度,它们具有不同的生命周期,并且更接近于各种数据片段的更改率。
发布于 2021-11-19 14:00:25
引入复杂的返回类型来最小化往返是一个有效的解决方案。
但是,我不会返回整个内部状态,因为我假设不是所有的客户端都需要所有的数据。这也可能是一个迹象,表明您有一个在粒度之外实现的业务逻辑,您应该将其移动到粒度中。
https://stackoverflow.com/questions/68710016
复制相似问题