2016-11-23 73 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

相关问题