【发布时间】:2016-09-10 11:45:32
【问题描述】:
在设计像 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 条件,如果我需要添加一个新的状态,我必须修改所有的 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() 方法必须添加到每个子类中,我认为这不是一个好习惯。在这种情况下还能做什么?
【问题讨论】:
-
我真的认为你需要 Replace Conditional with Polymorphism 重构
-
@ArnavBorborah 我研究了它,但想不出在这种情况下如何让它发挥作用。如果所有州都独立工作,我可以使用它,但在这里它们是相关的。如果水平在
Info,我需要允许Warning和Error等等。 -
如果我没记错的话,log4j 有一种方法可以接收级别和消息
log(Level, String),因此所需级别与设置级别的检查都在一个地方。然后像info(String)这样的方法是调用另一个方法的语法糖。
标签: java oop design-patterns