是否有任何模式可以按计划更改对象的状态?

时间:2016-01-17 18:08:36

标签: design-patterns architecture

情况如下:

  • 我需要在数据库中保留很多对象(比如说Food)(就我的情况而言,它是MySQL)。
  • 每个对象都有一个属性State,可以使用" FRESH"," STALE"或者" SPOILED"。
  • 每个对象根据某个计划更改其状态。例如,对象Bottle of milk是使用FRESH状态创建的,但在2天后它变为STALE,然后在接下来的3天后变为SPOILED

问题是:是否有任何模式允许我控制对象的状态并相应地更改它们?例如,我可以每30分钟运行一些脚本,选择所有对象,检查它们的状态并更改它们。但这种方法看起来并不理想,我试图找到更好的东西。

修改 每30分钟运行一个例程会增加数据库的负载(因为每次我都要选择记录进行分析)。我试图找到一个解决方案:

  1. 向RDBMS发出最低要求(在我的情况下是MySQL)
  2. 在实际状态变化和例程开始之间产生最小延迟(每30分钟运行一个例程意味着一些记录将最多延迟30分钟改变其状态)
  3. 可扩展,因为可能有更多州需要支持(这就是为什么JB Nizet的答案赢了并且不适合我)
  4. 我可以使用一些智能调度程序在内存中保存像timestamp -> [(object_id, next_state)]这样的有序映射(此任务最多可以使用128G)。

2 个答案:

答案 0 :(得分:2)

您不应该将状态存储在数据库中。你应该存储它变得陈旧的时刻,以及它变得被破坏的那一刻。

这样,您就不需要更改数据库中的任何内容。

要获取被破坏的项目,您只需要像

这样的查询
select * from item where now() >= spoileddate

要获取陈旧的项目,您只需要像

这样的查询
select * from item where now() >= staledate and now() < spoileddate

要获取新鲜的项目,您只需要像

这样的查询
select * from item where now() < staledate

BTW具有另一个优点:您可以在任何给定时间知道项目的状态,而不仅仅是当前状态。所以,如果你接到一个电话询问我三天前吃了产品xyz,我安全吗?&#34;你可以回答。

答案 1 :(得分:0)

JB Nizet所述,state属性不需要存储在数据库中。

通常,定期执行某些清理,维护等的实体的设计模式称为代理设计模式。

在你的情况下:

class FoodStateAgent
{
    void Run()  // called periodically from a Scheduler
    {
        // ...
    }
};

代理通常与调度程序一起工作 - 负责在定义的截止日期之前运行特定操作的类。