2016-11-23 53 views
0

假設兩個抽象類:像橋這樣的模式,但可以添加原始方法?

Log: 
    property:timestamp; 
    property:message; 

    LogFormatter: 
    (String *)formatlog:(Log)log; 

這看起來像一個橋樑,Log的行爲很像0​​和LogFormatterImplementor。在我看來,bridge不能將原始方法添加到Implementor。但我想動態添加屬性以登錄將來,並使用LogFormatter的子類對其進行格式化。這將打破Liskov Substitution principle

任何人有任何建議?

+0

如何使用組合擴展屬性?日誌可以包含一組「ExtendedLogProperty」或甚至只是一個「Map」。這將在合約中明確指出一些屬性總是存在並且是Log的模式的一部分,而其他屬性可能會丟失。此時,由於不必縮小'formatlog'的約定,因此不會中斷LSP。 – plalx

+0

爲您的技術找到一個日誌庫,不要重新發明輪子。 – BartoszKP

回答

0

如果Log有屬性時間戳和消息,我想你可能是LogEntry。

當您想要從其實現中抽象出一個抽象,以便二者可以非常獨立時使用橋接模式。我認爲這不是 你的情況。如果您只是想將LogEntry格式化爲字符串,只需將LogEntry作爲參數傳遞給返回String的LogFormatter方法即可。

如果您想動態添加屬性以便日後登錄,並使用LogFormatter的子類對其進行格式化。我會建議裝飾者或戰略模式,這取決於你真的想要什麼 。

編輯: 下面的僞代碼是一個如何可以實現這個與裝飾器如線程ID添加屬性到日誌條目 登錄{ 時間戳 消息 線程ID }

interface LogFormatter { 
    String format(Log); 
} 

// default implementation 
DefaultLogFormatter implements LogFormatter { 
    String format(Log) { 
     return Log.getTimestamp() + Log.getMessage(); 
    } 
} 

// decorated with thread Id 
ThreadIdLogFormatter implements LogFormatter { 
    LogFormatter formatter; 
    ThreadIdLogFormatter(LogFormatter formatter) { 
     this.formatter = formatter; 
    } 
    String format(Log) { 
     String threadid = Log.getThreadId(); 
     return formatter.format() + threadid; 
    } 
} 

LogFormatter formatterDefault = new DefaultLogFormatter(); 
LogFormatter formatterThreadId = new ThreadIdLogFormatter(formatterDefault); 

Log log = new Log("message"); 
// 2016-11-28 09:22:07.055 INFO message 
String logEntryDefault = formatterDefault.format(log); 
// 2016-11-28 09:22:07.055 INFO message (Thread 11) 
String logEntryThreadid = formatterThreadId.format(log); 
一個例子

就我個人而言,我只是定義一個抽象的LogFormatter(或接口)並實現LogFormatter子類,它將Log條目格式化爲某種形式的文本(line,xml,json,...)。設計模式很好,但在這種情況下可能並不是真的需要。

+0

我的意思是動態添加屬性LogFormatter的日誌和子類,你能解釋這更清楚,謝謝。 – Karl

+0

我剛剛編輯它。 HTH – Lini

相關問題