如何有效地跟踪和更新大量的值?

How to track and update a great many values efficiently?

我正在制作一个模拟中世纪政府和家庭的程序。人们(由 class Actor 的对象表示)出生、变老、生子和死亡。

这意味着我需要跟踪相当多的对象,并找出一些对象,例如每 year/month/week.

为每个被跟踪的人调用 update_age()

这带来了几个问题。我需要找到一些方法来遍历所有跟踪的 Actor 的集合。我还需要能够动态地添加到该集合,以说明出生率。

我的第一个想法是创建一个对象 Timekeeper,并使用一种方法为跟踪对象集中的每个对象调用 update_age()。然后,在主程序循环中,我会调用 Timekeeper 的方法。然而,这使得 Timekeeper 成为单例,这个概念并不总是一个好主意。由于我只是一个新手程序员,现在我想学习好的设计模式,而不是学错。

它仍然留给我一个问题,即如何让 set/list/dictionary 的所有被跟踪人员进行更新。

如果您是 运行 模拟,那么拥有一个包含各种组件的 "simulation engine" 当然是合理的设计。只要您不将它们实现为 application-wide 单例,就可以了。这实际上是一个很好的例子,说明了避免单身人士的建议实际上是什么!例如,不将它们作为单例将允许 运行 在同一进程中同时进行多个模拟。

像您这样的系统的一种常见设计是 event-based 设计。通过这样的设计,您将拥有一个用于模拟的事件管理器组件。它将支持在特定条件下调用的注册函数,例如给定的模拟时间已经过去。然后,您可以为模拟中的每个 Actor 注册要每隔一段时间触发的 update_age() 事件。

如果您走这条路,请记住您需要能够删除已注册的 Actor 不再相关的事件处理程序,例如如果他们在模拟中死亡。这可以通过为每个注册的事件创建一个唯一的 ID 来完成,以后可以用它来删除它。

避免单例的可能解决方案是 producer/consumer 模型和 queue。您有一个队列,其中有一个推送到队列的生产者和一个从队列中弹出的消费者。生产者 运行 在一个循环中,并且可以将函数添加到队列中,该队列应该是 运行 在给定模拟中的一组参与者上。然后消费者从队列中弹出函数并将它们应用到参与者列表中(按顺序)。

因此,例如,您可能会推送一个函数,该函数接受一个列表(演员)并将每个人的年龄更新为 1。或者一个函数可以找到每个成年女性演员并随机选择其中的 10% children , 他们随后被添加到列表中。

这不是我想到的第一个实现,但由于我已经看到了事件循环并且 pub/sub 提到了我想我会提供一个不同的替代方案。