由于它的普遍性,如果不首先找到相同类型的事件并检查发送给它的数据,就永远无法确定应该对任务提出什么要求。
据我了解,问题是几乎相同的数据在事件对象和任务对象中重复。
例如,您有Event { 'type': 'ItemPickup', data: { 'name': 'MagicSword', 'kind': 'weapon' } }。
然后你想添加一个任务来拾取魔法剑并创建Task { 'type': 'ItemPickup', data: { 'name': 'MagicSword' } }。
所以这就是问题所在,在这里您需要查找您是如何配置事件并将相同的数据放入任务对象中的。
我认为将这些数据移动到单独的对象中的解决方案应该很有效。
另一件看起来不正确的事情是你有type 字段,它暗示你需要有子类。
如果您创建 ItemPickupData、MoveData 等数据对象,这也将得到解决。
另一种方法是让Event 本身成为这个数据对象,并有这样的东西(伪代码):
class Event // base class for events with common data and methods
// the subclasses can be almost empty
class ItemPickupEvent extends Event
class MoveEvent extends Event
class Task
_requirements = [
new ItemPickupEvent('MagicSword'),
// and maybe it is even better to wrap events into "Requirment" objects,
// which can, for example, be marked as completed
new Requirement(new MoveEvent('OldForest')),
...
]
然后您可以通过这种方式管理需求:
class Task
isComplete(event)
complete = false
// go over requirements to see if this task is complete
for requirement in this._requirments:
complete = complete && requirement->isComplete(event)
return complete
class Requirement
isComplete(event)
# check event class and properties to understand if the requirement is satisfied
if class(event) == class(this._event):
if event.isNameMatches(this._event):
this->_complete = true
return this->_complete
也可以在没有类名检查的情况下完成。
这个想法是让基础Requirement 类对每个事件类都有特殊的方法,并默认拒绝它们。
然后子类可以处理特定的事件类型:
class Requirement
isComplete(event)
// redirect the type detection to event object
return event->isComplete(this)
isCompleteItemPickup(event)
return false
isCompleteMove(event)
return false
class ItemPickupRequirement
isCompleteItemPickup(event)
// here we know that event is ItemPickupEvent
if event.isNameMatches(this._event):
this->_complete = true
return this->_complete
class MoveRequirement
isCompleteItemPickup(event)
// here we know that event is MoveEvent
if event.isNameMatches(this._event):
this->_complete = true
return this->_complete
Requirment 类的 isComplete 方法从 Task 类中使用,它将类型检测重定向到事件对象。
事件对象然后将自身传递回需求的适当方法:
class Event
isComplete(requirement) // should be implemented in subclasses
class ItemPickupEvent
isComplete(requirement)
// here we call the specific requirement method
// now we know the exact event object type (it is ItemPickupEvent)
return requirement->isCompleteItemPickup(this)
class MoveEvent
isComplete(requirement)
return requirement->isCompleteMove(this)
结构可能看起来有点复杂,但根据具体情况,您可能需要Requirement 类及其子类(例如,可以有通用的ItemPickupRequirement 和一些特定的PowerItemPickupRequirement)。