处理一个解析事件日志的项目,然后根据这些事件的属性更新模型。我一直很懒于“完成它”,而更关心前期优化、精益代码和正确的设计模式。主要是自学实验。我感兴趣的是更有经验的设计师认为哪些模式是相关的,或者哪种类型的伪代码对象架构是最好的、最容易维护的等等。

单个日志中可以有 500,000 个事件,大约有 60 种事件类型,所有这些事件共享大约 7 个基本属性,然后根据事件类型具有 0 到 15 个附加属性。事件类型是日志文件中每行的第二个属性。

因此,我尝试了一个非常丑陋的命令式解析器,它逐行遍历日志,然后逐行处理事件。然后我尝试了使用“nextEvent”模式的词法规范,该模式在循环中调用并进行处理。然后我尝试了一种普通的旧“解析”方法,它永远不会返回,只是向注册的侦听器回调触发事件。我尝试了无论事件类型如何的单个回调,以及特定于每种事件类型的回调方法。

我尝试过使用所有可能属性的联合的基本“事件”类。我试图避免“新事件”调用(因为可能存在大量事件,并且事件对象通常是短暂的)并使用带有原始属性参数的每种类型的回调方法。我尝试为 60 种事件类型中的每一种创建一个子类,并使用具有 7 个公共基本属性的抽象事件父类。

我最近尝试更进一步,使用命令模式为每个事件类型放置事件处理代码。我不确定我喜欢这个,它与每种类型的回调方法非常相似,只是代码位于类型子类中的执行函数内,而不是每种类型的回调方法。

问题是很多模型更新逻辑是共享的,并且很多是特定于子类的,我刚刚开始对整个事情感到困惑。我希望有人至少能给我指出一个考虑的方向!

有帮助吗?

解决方案

出色地...对于一件事,而不是具有所有属性联合的单个事件类,或 61 个事件类(1 个基本类,60 个子类),在具有如此多变化的场景中,我很想拥有一个使用一个属性包(字典、哈希表、让你的船漂浮)来存储事件信息。事件的类型只是放入包中的又一个属性值。我倾向于这种方式的主要原因只是因为我不愿意维护任何东西的 60 个派生类。

最大的问题是……你必须做什么 当您处理事件时。您是否将它们格式化为报告,将它们组织到数据库表中,在发生某些事件时唤醒人们......什么?

这是一个事后解析器,还是一个实时事件处理程序?我的意思是,您是在事件发生时监视日志,还是只是在第二天解析日志文件?

其他提示

考虑一个策略对象的 Flyweight 工厂,每个“类”事件一个。

对于每一行事件数据,从享元工厂中查找合适的解析策略,然后将事件数据传递给该策略进行解析。60 个策略对象中的每一个都可以属于同一类,但配置有不同的字段解析对象组合。如果没有更多细节,很难说得更具体。

可能 散列适配器对象 (如果你能在网上找到一个很好的解释 - 他们似乎缺乏。)

就在顶部:

我喜欢接受的答案中关于只有一个带有属性映射的类的建议。我还认为行为也可以这样组装:

class Event
{
    // maps property name to property value
    private Map<String, String> properties;

    // maps property name to model updater
    private Map<String, ModelUpdater> updaters; 

    public void update(Model modelToUpdate)
    {
        foreach(String key in this.properties.keys)
        {
            ModelUpdater updater = this.updaters[key];
            String propertyValue = this.properties[key];

            updaters.updateModelUsingValue(model, propertyValue);
        }
    }

}

ModelUpdater 类未在图中显示。它根据属性更新您的模型。我编好了循环;这可能是也可能不是您的算法的实际情况。我可能会让 ModelUpdater 更像一个界面。每个实施者将针对每个属性并更新模型。

那么我的“主循环”将是:

Model someModel;

foreach(line in logFile)
{
    Event e = EventFactory.createFrom(line);
    e.update(someModel);
}

EventFactory 从文件构造事件。它根据事件的属性填充两个映射。这意味着有某种方法可以将属性与其关联的模型更新程序相匹配。

我没有任何花哨的图案名称给你。如果您有一些复杂的规则,例如事件具有属性 A、B 和 C,然后忽略 B 的模型更新程序,则必须以某种方式扩展此方法。最有可能的是,您可能需要使用规则对象模式以某种方式将一些规则注入到 EventFactory 中。就这样,有一个适合您的模式名称!

我不确定我是否正确理解了这个问题。我假设有一个复杂的“模型更新逻辑”。不要将其分布在 60 个类中,将其保留在一个位置,将其从事件类中移出(中介模式,某种程度)。

您的调解器将与事件类一起使用(我不知道您如何在此处使用享元),事件可以自行解析。

如果更新规则非常复杂,则无法使用通用编程语言真正解决该问题。考虑使用基于规则的引擎或类似的东西。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top