我的Java Web应用程序中有许多软件包。在其中一些我使用这个结构:
public class Foo {
private static Logger logger = LoggerFactory.getLogger("com.XXX");
public void bar() {
Foo.logger.debug("Method bar() was just called");
}
}
当然,这只是一个例子。一切正常,但我不喜欢许多类中记录器初始化的想法。这是一个明显的代码重复。我想将它移动到一个帮助类,让所有其他类访问它。这是一个正确的想法吗?或者也许还有其他“最佳实践”或模式?
答案 0 :(得分:8)
说这是代码重复就像是说75%的类中有import java.util.*
是代码重复。或者你发现自己经常写public class ...
。它不是重复逻辑。它重复了样板代码。
代码重复只涉及复制逻辑时的设计气味。如果有太多的样板代码,那真的是语言设计。你真的不应该担心什么。
缺点是,如果放弃层级结构,则无法微调日志记录。
答案 1 :(得分:5)
如果你使用集中的全局静态记录器constrcut而不是常见的Log4J调用/ inits,我认为你不会赢得任何东西。
如果你写
private static Logger logger = LoggerFactory.getLogger("com.XXX");
logger.info("Hello World");
或类似的东西
GlobalLogger.info(this, "LogMessage"); //Singleton...
...不会让你的代码更“可读”。
答案 2 :(得分:3)
您可以编写自己的实用程序类,它包装全局记录器并实现对记录器方法的静态委托。然后只需对此类进行静态导入:
public class MyLogger {
private static Logger logger = LoggerFactory.getLogger("application");
public static void debug(String s) {logger.debug(s));}
public static void debug(Class<?> caller, String s) {
LoggerFactory.getLogger(caller.getName()).debug(s);
}
// ...
}
用法:
import static MyLogger.*;
public class Foo {
public void bar() {
// makes use of static import!
debug("Method bar() was just called");
debug(this.getClass(), "Method bar() was just called");
}
}
添加了示例debug
委托的重载版本,该委托采用类对象并使用相应的Logger。
答案 3 :(得分:1)
不建议这样做,因为您将失去Log4j的层次化日志记录功能(如果这是您正在使用的),在包树的不同级别添加不同的appender非常有用。我不会这样做,因为你会丢失有关哪个类创建了日志消息的信息。
答案 4 :(得分:1)
使用实用程序记录器类封装第三方依赖项(即Log4j)是有意义的。
例如,如果团队决定从Log4j切换到NextBigThingLogger,他们只需更新他们的MyLogger类,而不更新其他应用程序类。
更清洁,更容易维护。
Apache API,甚至Java语言本身都充斥着“设计气味”,但这并不意味着我们不应该回应它们。
答案 5 :(得分:0)
我认为你是在追随Singleton设计模式。不是java程序员,我从谷歌那里挖出来了:
http://www.javacoffeebreak.com/articles/designpatterns/index.html
答案 6 :(得分:0)
您可以为记录器创建Adapter pattern。就我而言,我扩展了记录器以包含所有记录器功能。然后将其制作成单身人士。
public class LoggerAdapter extends Logger {
private LoggerAdapter instance;
private Logger logger;
private LoggerAdapter() {
}
public static LoggerAdapter getInstance(Clazz<?> clazz) {
if (instance == null) {
instance = new LoggerAdapter();
}
instance.logger = logger = LoggerFactory.getLogger(clazz.getName());
return instance;
}
@Override
public void trace(Object object) {
logger.trace(object);
}
//Other overridden methods here...
};
基本上是一个动态变化的记录器......