C# 什么';解决相互作用组合爆炸的最佳方法是什么?
我现在正在做的一件事与游戏有一些相似之处。为了便于说明,我将用一个虚构的、假设的游戏中的例子来解释我的问题 让我们称之为死亡冲击波4:死亡。在DB4中,您有许多C# 什么';解决相互作用组合爆炸的最佳方法是什么?,c#,design-patterns,software-design,C#,Design Patterns,Software Design,我现在正在做的一件事与游戏有一些相似之处。为了便于说明,我将用一个虚构的、假设的游戏中的例子来解释我的问题 让我们称之为死亡冲击波4:死亡。在DB4中,您有许多Ship对象,它们在旅行时周期性地、随机地遇到现象。给定的现象可能对遇到它的船舶产生零、一或多个影响。例如,我们可能有四种船舶和三种现象 Phenomena ========================================== Ships GravityWell Blac
Ship
对象,它们在旅行时周期性地、随机地遇到现象。给定的现象
可能对遇到它的船舶产生零、一或多个影响
。例如,我们可能有四种船舶
和三种现象
Phenomena
==========================================
Ships GravityWell BlackHole NebulaField
------------ ------------------------------------------
RedShip +20% speed -50% power -50% shield
BlueShip no effect invulnerable death Effects of Various
GreenShip -20% speed death +50% shield Phenomena on Ships
YellowShip death +50% power no effect
现象
==========================================
飞船重力井黑洞星云
------------ ------------------------------------------
红船+20%速度-50%功率-50%护盾
蓝军无效果无敌各种死亡效果
绿船-船上20%速度死亡+50%护盾现象
黄舰死亡+50%能量无效
此外,效果
可能会相互影响。例如,同时位于重力井
和星云场
的绿色飞船
可能会在生成的速度效应
和ShieldeEffect
之间产生某种协同作用。在这种情况下,协同效应本身就是一种效应
——例如,这种相互作用可能会产生一种PowerLevelSynergyEffect
。除了作用在船舶上的效应集
之外,无需任何信息来确定最终结果
你可能开始看到这里出现了一个问题。作为一种简单的第一种方法,要么每艘船都必须知道如何处理每一种现象,要么每一种现象都必须知道每艘船的情况。这显然是不可接受的,因此我们希望将这些责任转移到其他地方。显然这里至少有一个外部类,可能是某种类型的中介
或访问者
但是最好的方法是什么呢?理想溶液可能具有以下特性:
- 添加新的
发货
与添加新的现象
一样容易
- 不产生任何效果的交互是默认的,不需要额外的代码来表示。约定优先于配置
- 了解<代码>效果代码>如何相互作用,并能够管理这些相互作用以决定最终结果
我想我已经决定了我的方法,但我很想知道什么是最好的设计共识。你从哪里开始?你会探索什么途径
后续更新:谢谢大家的回复。这就是我最后要做的。我的主要观察结果是,不同的效应
的数量相对于可能的现象
×船舶
交互作用的数量似乎很小。也就是说,尽管存在许多可能的交互组合,但这些交互的结果种类数量较少
例如,您可以看到,虽然表中有12种交互组合,但只有五种效果:速度修改、力量修改、盾牌修改、无敌、死亡
我引入了第三个类,InteractionResolver
,用于确定交互的结果。它包含一个字典,将Ship现象
对映射到效果
(基本上是执行效果的委托和一些元数据)。每个飞船
都会收到一个效应堆栈
,对应于交互计算结果完成时它所体验的效应
Ships
然后使用EffectStack
通过向其现有属性和属性添加修改器来确定效果对其产生的实际结果
我喜欢这个,因为:
Ship
s不需要了解现象
Ship
-现象
关系的复杂性被抽象为交互解析器
- 如何解决多种可能的复杂效果的详细信息由
InteractionResolver
抽象出来。船舶只需在必要时应用效果
- 这可以实现其他有用的重构。例如,船舶处理效果的方式可以通过制定
效应处理器策略来区分。默认情况下可能会处理所有效果,但是,比如说,BossShip
可能会通过使用不同的EffectProcessorStrategy
忽略次要效果
这不是一个很好的答案,但对我来说,这相当于“属性模式”。关于这一点,有一个著名的耶格咆哮,我想它会给你一些像样的建议
这看起来像是经典的OOP多态性/访问者困境。然而,您的需求使它更容易
基本上,我将创建一个基类
Ship
,所有具体的船舶都从中派生。此类将具有以下方法:
class Ship
{
void encounterBlackHole() {}
void encounterNebula() {}
... etc. ...
};
具有空的默认实体。当你添加一个新的现象时,你只需要添加一个新的空体方法。(这些方法可能有参数,如黑洞的坐标或重量等)
对于效果和它们的相互作用-我认为你应该添加更多关于你想要它的信息,例如,这些相互作用是罕见的还是常见的,它们是以某种形式累积的,它们是否局限于它们控制的一组有限的变量…一个整数
IShip myShip = myShip.AddPhenomena(PhenomenaGeneratedByAFactoryForThisShip);
class Ship():
def __init__(self,type):
self.type=type
def encounterPhenomena(self,type): # let Phenomena to process ship
p = Phenomena(type)
p.process(self)
class Phenomena():
processTable = {}
def __init__(self,type):
self.type=type
def process(self,ship):
try:
self.processTable[self.type](ship.type) #query the internal table to process ship
except:
pass #if Phenomena don't know this ship type then no process..
def addType(type,processMethod):
processTable[type]=processMethod #add new Phenomena, and add processMethod
def run():
A = Ship(type = 'RedShip')
A.encounterPhenomena(type='GravityWell');