事件日志解析器的适当设计模式?
在分析事件日志的项目上工作,然后根据这些事件的属性更新模型。我一直懒于"完成",而更关心前期优化,精益代码和适当的设计模式。主要是自学实验。我对更有经验的设计师认为哪些模式相关,或者哪种类型的伪编码对象体系结构将是最佳,最容易维护的感兴趣,等等。
单个日志中可以有500,000个事件,并且大约有60种事件类型,所有这些事件共享大约7个基本属性,然后根据事件类型具有0到15个其他属性。事件的类型是日志文件每行中的第二个属性。
因此,对于我来说,我尝试了一个非常丑陋的命令式解析器,该解析器逐行浏览日志,然后逐行处理事件。然后,我尝试了使用" nextEvent"模式的词汇规范,该规范在循环中被调用并进行处理。然后,我尝试了一个简单的旧" parse"方法,该方法永远不会返回,只会向注册的侦听器回调触发事件。我既尝试了单个回调(无论事件类型如何),也尝试了特定于每种事件类型的回调方法。
我已经尝试过将所有可能的属性合并在一起的"事件"基类。我试图避免"新事件"调用(因为可能存在大量事件,并且事件对象通常寿命很短),并且每种类型的回调方法都带有原始属性参数。我尝试为60个事件类型的每个子类提供一个带有7个公共基本属性的抽象Event父类的子类。
我最近尝试更进一步,并使用"命令"模式为每种事件类型放置事件处理代码。我不确定我是否喜欢这种方法,它是否确实类似于每种类型的回调方法,只是代码位于类型子类的执行函数中,而不是每种类型的回调方法。
问题在于,很多模型更新逻辑是共享的,并且很多都是特定于子类的,而我刚开始对整个事情感到困惑。我希望至少有人可以指出我要考虑的方向!
解决方案
可能是散列的适配器对象(如果我们在网络上找不到它的很好的解释,它们似乎是缺少的。)
考虑一个策略对象的轻量级工厂,每个"类"事件一个。
对于每行事件数据,请从flyweight工厂中查找适当的解析策略,然后将事件数据传递给该策略以进行解析。 60个策略对象中的每个策略对象都可以属于同一类,但是配置为具有不同的字段解析对象组合。如果没有更多细节,很难更具体。
好吧...对于一件事,而不是具有所有属性的并集的单个事件类,或者61个事件类(1个基,60个子对象),在变化如此之大的情况下,我很想拥有一个单一的事件类。使用属性包(字典,哈希表,w / e使船漂浮)的事件类来存储事件信息。事件的类型只是放入包中的另一个属性值。我倾向于这种方式的主要原因仅仅是因为我不愿维护60个派生类的任何东西。
最大的问题是……在处理事件时,它们与事件有什么关系。我们是否将它们格式化为报表,将它们组织为数据库表,如果发生某些事件就将人们叫醒……是什么?
这是要成为事后解析器,还是实时事件处理程序?我的意思是,我们是在事件发生时监视日志,还是第二天仅分析日志文件?
我不确定我是否正确理解了问题。我假设有一个复杂的"模型更新逻辑"。不要在60个类中分发它,不要将其放在一个地方,将其从事件类中移出(介体模式,类似)。
调解员将使用事件类(我在这里看不到如何使用Flyweight),事件可以自行解析。
如果更新规则非常复杂,那么我们将无法使用通用编程语言真正解决问题。考虑使用基于规则的引擎或者类似的东西。
就在顶部:
我喜欢接受的答案中关于只包含一个带有属性图的类的建议。我也认为行为也可以这样组装:
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中。我们去了,这里有一个模式名称!