在设计像log4j这样的类时,如何处理条件语句?
以log4j为例,一个类可以有不同的级别(信息,警告,错误,其他......)。现在要打印不同级别,每个级别需要不同的方法。所以可以有如下基本设计:
public class CustomLogger {
enum Level{
INFO, WARNING, ERROR;
}
private Level level;
public CustomLogger(Level level) {
this.level = level;
}
public void info(String s){
if(level == Level.INFO || level == Level.WARNING || level == Level.ERROR){
System.out.println(s);
}
}
public void warning(String s){
if(level == Level.WARNING || level == Level.ERROR){
System.out.println(s);
}
}
public void error(String s){
if(level == Level.ERROR){
System.out.println(s);
}
}
}
我猜这个设计的问题是它有太多的条件,如果我需要添加一个新状态,我将不得不修改所有if情况。所以我认为可能是更好的设计如下:
有一个State
超类,它由类Info
,类Warning
和类Error
扩展。 State
类包含方法printInfo()
,printWarning()
和printError()
。所有子类都实现这些方法,并在需要时留空。作为示例,类Warning
看起来像:
class Warning extends State{
public void printInfo(String s){
//don't print
}
public void printWarning(String s){
System.out.println(s);
}
public void printError(String s){
System.out.println(s);
}
}
现在CustomLogger
将与State
建立关联,并在某个时刻注入CustomLogger
,State
中的所有方法都会调用public class CustomLogger {
private State state;
public CustomLogger(State state) {
this.state = state;
}
public void info(String s){
state.printInfo(s);
}
public void warning(String s){
state.printWarning(s);
}
public void error(String s){
state.printError(s);
}
}
类实现的方法。类似的东西:
State
尽管这消除了条件情况,但它引起了方法调用的依赖性。如果我添加一个新的printState()
那么状态$
方法必须添加到每个子类,我想这不是一个好习惯。在这种情况下还能做些什么?
答案 0 :(得分:1)
在这种情况下,最佳答案取决于系统的要求将来如何变化。即使您遵循Open/close principle
,也无法阻止违反此原则的所有可能情况,因此您尝试在设计中覆盖您认为更有可能出现的情况。
无论如何,您的案例研究的一个很好的解决方案类似于Java Logger
实现的解决方案。数值与Logger
级别相关联(每个可能的Level
都有其值),允许您检查当前Logger
是否应该使用单个{{if
向日志写入任何内容1}}。此外,在不修改当前代码的情况下扩展其行为非常容易。
例如,当您致电Logger#info(String)
时:
public void info(String msg) {
log(Level.INFO, msg);
}
方法log
如下:
public void log(Level level, String msg) {
if (!isLoggable(level)) {
return;
}
// do any logging you want here
}
最后是关键isLoggable
:
public boolean isLoggable(Level level) {
if (level.intValue() < levelValue || levelValue == offValue) {
return false;
}
return true;
}
其中levelValue
是Logger
的“当前有效等级值”。