繁体   English   中英

“静态类”还是传递引用?

[英]“static class” or pass references around?

我是为客户/服务器模型海战视频游戏(大学课程)设计服务器的团队的成员。 我们有一个相当具体(我认为是很好)的系统设计,但是有一个方面困扰着我。

系统的基本布局是:

Server [thread] (handles incoming connections)
|
Game [thread] (deals with game events in it's work queue and sending messages to clients)
|--Environment (holds environment variables, deals with collision)
|--Client(s) [thread] (handles incoming messages from client sockets and adds events to the Game's work queue)
    |--Ship (holds game data, eg: hit points, fire power, etc)
    |--Parser (parses client messages and creates game event objects)
|--GameEvent (event objects held in a queue that can preform appropriate work and send appropriate responses to clients)

现在,我的问题是,Client和GameEvent(以及环境,一旦我们了解到它)都需要引用它们所属的Game对象。

客户需要将GameEvent添加到游戏的工作队列中。

GameEvent需要访问其他游戏数据(其他客户的飞船,环境)。

是否有更好/更常规的方法代替让这些对象存储对其游戏的本地引用? 将Game的所有方法都声明为静态方法怎么样? 我们一次只需要处理一个游戏,因此就不会有一个以上的Game实例。

我确定对于具有一个中央对象的系统有一个约定,该中央对象具有许多需要引用它的辅助对象。

您是否考虑过使用像Guice这样的依赖注入框架? 那里有称为“模块”的配置类,您在其中将接口Game绑定到实现(您可以决定要单例还是新实例)。 客户端类看起来像

public class Client {
   private final Game game;

   @Inject
   public Client(Game game) {
      this.game = game; 
   }   

   ... 
}

可以照常构造此类,提供Game实例(例如,使用模拟Game类进行测试)。 但是,如果让Guice为您创建此实例(不需要直接创建该实例,则在另一个类注入Client的情况下也可以正常工作),您会自动获得在Guice模块中指定的实例。

我知道需要花费一些时间来解决这个概念,但是我可以确认这可以使代码更简洁,更灵活。

如果真的只有逻辑永远一个实例,你可以使用一个单例。 单例的规范形式为:

public enum Singleton {
    INSTANCE;

    // fields and methods here
}

这样,您不必将所有内容都塞进静态方法中(不过,如果您要编写引用INSTANCE静态方法,也可以)。 任何想要访问单例的代码都只使用Singleton.INSTANCE ,并且如果不需要的话,也不必传递它。

传递引用将使您的选项保持打开状态,它仍然可以是对实际静态对象的引用。 请求上下文的概念也可能有用,该对象包含处理单个请求所需的所有引用,然后将其传递出去。

检出控制反转(IOC)和容器。

这样,在Client和GameEvent类中,只要需要访问游戏,就可以执行以下操作:

var game = IoC.Resolve<Game>(); 

然后使用游戏实例方法...

将引用传递给构造函数并存储它们没有错。 您还应该引入一个接口,该接口可以介导游戏与客户端和环境对象之间的访问。

我强烈建议不要在设计中使用单例或静态类。 造成这种情况的原因很多,但是可能最直接影响您的原因是它使测试变得非常困难。 在测试时,可能会有不止一个Game实例。

改善具有多个辅助对象的一个​​大型中心对象的常见约定是尝试避免一个大型中心对象。 您注意到,“游戏”的不同客户有不同的需求。 也许您在Game上的界面太宽了。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM