2008-09-18 74 views
6

使用解析事件日誌的項目,然後根據這些事件的屬性更新模型。我對於「完成任務」一直很懶惰,更關心前期優化,精益代碼和適當的設計模式。主要是一個自我教學實驗。我對更有經驗的設計師認爲相關的模式感興趣,或者什麼類型的僞碼對象體系結構最好,最容易維護等等。適用於事件日誌解析器的設計模式?

可以有單個日誌中的500000點的事件,並有大約60類型的事件,所有這些共享關於7個鹼基的屬性,然後根據各自的事件類型0至15的其他屬性。事件的類型是每行中日誌文件的第二個屬性。

因此,我試過了一個非常難看的命令解析器,它逐行逐行掃描日誌,然後逐行處理事件。然後我嘗試了一個使用「nextEvent」模式的詞法規範,該模式在循環中調用並進行處理。然後我嘗試了一個普通的「解析」方法,它永遠不會返回,只是將事件引發到註冊的偵聽器回調。無論事件類型如何,我都嘗試了單個回調,並且針對每種事件類型都使用了回調方法。

我試過了一個基礎「事件」類與所有可能的屬性的聯合。我試圖避免「新事件」調用(因爲可能有大量的事件並且事件對象通常很短),並且每種類型的回調方法都帶有基本屬性參數。我已經嘗試了60個事件類型的每一個具有7個公共基本屬性的抽象事件父類的子類。

我最近試圖進一步採用Command模式來爲每個事件類型添加事件處理代碼。我不確定我是否喜歡這樣,它和每種類型的回調方法非常相似,只是代碼在類型子類中的執行函數中,而不是類型中的回調方法。

的問題是,很多模型更新的邏輯是相通的,很多的它是特定的子類,我剛開始弄不清楚整個事情。我希望有人能夠至少指出我想要考慮的方向!

回答

3

嗯......一兩件事,而不是一個單一的事件類的所有屬性,或61事件類(1個基地,60級潛艇)的聯盟,有這麼大的變化的情況下,我會忍不住擁有一個使用屬性包(字典,散列表,用W/E漂浮你的船)來存儲事件信息的事件類。事件的類型只是一個可以放入包中的屬性值。我傾向於這種方式的主要原因是因爲我不願意維護60個派生類的任何東西。

最大的問題是...你有什麼與你處理它們的事件。您是否將它們格式化爲報告,將它們組織到數據庫表中,如果發生某些事件會喚醒人們......什麼?

這是否意味着是事後分析器,還是實時事件處理程序?我的意思是,你是在事件進入時監視日誌,還是在第二天解析日誌文件?

+0

嗯,我很確定我想堅持使用原語作爲事件屬性,因爲它們是已知的並且是常量,我非常關心性能。我想生成一個聚合信息報告的事件塊。事後,但我想要有序地(確定性地)處理? – Josh 2008-09-18 16:41:30

1

可能Hashed Adapter Objects(如果你能找到它的網絡上的一個很好的解釋 - 他們似乎缺乏。)

+0

我結束了使用這樣的東西,隨着物業袋方法。我基本上只是提取事件類型作爲包的第二個屬性,並將處理程序附加到60個不同類型。感謝您的正式參考。 – Josh 2008-10-06 14:34:06

2

考慮戰略目標的飛錘工廠,每一個事件的「類」。

對於事件數據的每一行,查找從飛擺工廠適當的解析策略,然後將事件數據傳遞到策略用於解析。 60個策略對象中的每一個可以是相同的類,但是配置有不同的字段解析對象組合。沒有更多的細節,它有點難以更具體。

+0

解析器組件已經完成,它是一個有限狀態機,對於所有的事件都非常有效。對不起,如果我不清楚。問題是我不知道如何處理解析後的事件。 – Josh 2008-09-18 16:48:06

0

我不確定我是否正確理解問題。我假設有一個複雜的「模型更新邏輯」。不要通過60個課程分發這些內容,將它保存在一個地方,將它從事件類中移出(調解器模式,類型)。

你的介體將與事件類一起工作(我不知道你怎麼能在這裏使用飛錘),事件可以解析自己。

如果更新規則非常複雜,那麼使用通用編程語言無法真正解決這個問題。考慮使用基於規則的引擎或類似的東西。

1

剛剛送走了頂部:

我喜歡有地圖一個屬性只有一個類中接受的答案的建議。我也認爲行爲可以這樣組裝:

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注入一些規則。你去了,有一個模式名稱給你!