这是什么模式,我应该这样做吗?


9

我正在使用Flash开发和Flash CS5在AS3中制作游戏。一切都是面向对象的。我想知道,是否应该有一个“网关”类,该类具有对其他类的所有实例化的属性引用,并且我只是将此网关类传递给新对象,因此它们可以访问每个类。像这样:

 var block:Block = new Block(gateway);

 //In the block class:
 this.gateway.player.setHealth(100);
 //Or:
 this.gateway.input.lock();

这是像单例模式一样吗?我应该这样做吗?

Answers:


13

这称为 上下文对象设计模式,它比单例模式更好。

  • 上下文对象有助于测试,因为您可以将模拟上下文传递给要测试的函数。单身人士阻碍了这一点,因为要模拟单身人士,您需要使其不成为单身人士。
  • 上下文对象使您的“全局状态”变得明确,因此更易于推理。如果函数不使用上下文对象,则说明它不使用任何全局上下文状态。对于单例或全局变量,您没有任何保证。
  • 如果不使用它们,上下文对象会稍微慢一些,因为在所有函数调用中都添加了另一个参数。如果您确实使用它们,它们可以比全局变量更快,并且几乎总是比单例更快。
  • 上下文对象更易于实现;通常它们以正常方式生活在堆或堆栈上。单例有棘手的问题,涉及许多语言中的线程。

所以不,这不是单例,它比单例好。

但是,您仍然遇到了很多麻烦的情况-您将所有内容都保留在一个局部变量中的事实使它更加明确,但仍会造成关注点的严重混淆。牢记一责制。从某种意义上说,有一个拥有玩家和当前关卡的上下文(它们是相关的),但是为什么相同的上下文拥有您的键盘输入呢?

考虑不同级别的上下文,例如:

  • GameplayContext-拥有玩家,敌人,关卡的几何形状等
  • InputContext-拥有键盘和鼠标手柄,输入事件等。
  • GraphicsContext-拥有纹理,窗口句柄等
  • GlobalContext-拥有GameplayContext,GraphicsContext和InputContext。这是您要应用服务定位器模式的地方,以便能够根据需要将某些上下文换成其他上下文。也许,为了进行快速迭代和测试,这应该是一个真实的全局变量-只需意识到,无论何时使用它,都将增加技术负担

这些上下文仍然在某种程度上混淆了关注点-也许某些事件处理程序采用了GameplayContext,而实际上只需要玩家-但职责已明确列出。您知道,带有GameplayContext的东西不会加载纹理。采用InputContext的东西不能杀死玩家。


+1好答案。但是,某些速度或线程问题实际上并未在此上下文中应用(ActionScript3不支持线程,并且在使用AS3时,许多在C ++中起作用的速度改进机制并不适用)。
bummzack,2010年

我不太了解AS3VM,但在大多数动态语言,传递/接收/使用本地的成本仍然较快(阵列查找)比查找全局(哈希查找)的成本,快于调用一个函数(很多东西)来实现它。因此,我认为建议仍然适用。

0

这看起来不像Singleton模式。以我的理解,您正在将引用重要游戏对象的对象传递给所有实例。

如果这将是Singleton模式,您将具有:

AudioManager.getInstance().playSound(XY);

而在您的情况下,您可能会:

this.gateway.getAudioManager().playSound(XY);

它看起来基本相同,但实际上并非如此。如果要替换AudioManager为新的(扩展类)如ExtendedAudioManager,则可以使用Singleton模式打墙。您的网关方法可以很好地解决这一问题。

这种方法的缺点是您必须四处走动gateway。的服务定位器模式(由乔Wreschnig提出这个线程),看起来像一个很好的替代你的“网关模式”。

有时,最好只使用简单明了的方法运行,而不要过度设计。特别是当它是一个小型项目或原型时。也许你可以做gateway一些全局变量。Game.gateway并运行它。


-2

包括Singleton模式在内的大多数此问题的解决方案都涉及静态变量的使用。如果只有一个玩家,则可以将Player设为单例类,这意味着您可以通过Player.currentPlayer之类的内容访问Player实例。但是,许多人反对Singletons。您还可以拥有一个ResourceManager或类似的类,其中包含对各种有用的全局或pretty-darn-global变量的静态引用。在您的代码中,您还可以使“网关”变量可以静态访问,而不是通过在各处传递代码来夸大代码。


自从我做出这个回答以来,这个问题已经发生了很大的变化,以至于似乎不值得对其进行编辑。
格雷戈里·艾弗里·威尔

2
除了标题,问题没有任何改变。
bummzack 2010年

1
什么?除标题外,没有其他任何更改。-1
AttackingHobo 2010年

我想我在想标题。我记得原来的标题是“我应该怎么做?”之类的东西。做出答案时,我很可能会误读最初的标题/问题。
格雷戈里·艾弗里·威尔
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.