2

我看到有人写了一个 java LOG API,就像下面的代码一样。这个想法是客户端不必每次都调用 LogUtil.getInstance()。但是我的感受是这不是java的惯用语吗?

public class LogUtil{
private static LogUtil instance;
private Object current;//some Logger
private static LogUtil getInstance(){
    if(instance == null){
        instance = new LogUtil();
    }
    return instance;
}

private static void debug(String text){

}

public static LogUtil init(){
    //dosomething with
    // getInstance().current;
    return getInstance();
}

public static LogUtil logSomething(String text){
    //dosomething with
    // getInstance().current;

    return getInstance();
}
public static LogUtil anotherMethod(String text){
    //dosomething with
    // getInstance().current;

    return getInstance();
}

}

反对这种设计的论据是什么(使每个方法都是静态的)?

4

4 回答 4

6

这基本上是“全局变量”的一种变体,问题总是一样的:你只能拥有其中一个。如果您需要替换或扩展它,很多代码都会中断。

为什么其他日志框架使用工厂:

 private final static Logger log = LoggerFactory.getLogger( Foo.class );

这样,我有一个全局变量(而不是你的情况下的几十个)。这并不理想,但至少给我一个单点故障。

这种方法允许我Logger用几乎任何东西扩展/替换接口,而无需更改代码中的数百个位置。

也就是说:不要编写自己的日志 API。使用slf4j。你需要花一点时间来理解它是如何工作的,但是许多聪明的人已经花费了数年时间来构建一个伟大的日志框架,它解决了你还不知道的数千个问题。

编辑

它不是一个通用的日志工具。但更多的是产生商业Word文档的“记者类”。

然后看看静态导入。

我建议公开一个getInstance()方法,但给该方法一个更有用的名称。然后,您可以在其他任何地方静态导入这个单一方法,并在没有LogUtil.前缀的情况下调用它。

于 2013-10-18T09:37:31.130 回答
0

使方法静态化的一个经验法则是:问问自己“调用这个方法是否有意义,即使还没有构造 Obj?” 如果是这样,它肯定应该是静态的。" 在您的示例中,像 logSomething()、anotherMethod() 之类的操作正在使用实例执行某些操作。由于这些方法没有实例就没有意义,它们应该是非静态的。只有 getInstance() 方法应该是静态的。

将所有内容都设为静态的主要缺点是您无法在运行时交换、覆盖或选择方法实现。该线程对静态的缺点进行了很好的讨论:在Java中,类上的静态方法有什么缺点吗?.

于 2013-10-18T09:51:30.637 回答
0

静态类是 Helper 类,对于您的 LogUtil 静态类,我将声明所有方法以返回 void:

public class LogUtil{
private static LogUtil instance = new LogUtil(); //Initialization here
private Object current;//some Logger

private static LogUtil getInstance(){
}

private static void debug(String text){

}

public static void init(){
    //dosomething with
    // instance.current;
}

public static void logSomething(String text){
    //dosomething with
    // instance.current;
}
public static LogUtil anotherMethod(String text){
    //dosomething with
    // instance.current;
}
}

但是我对那个设计不太满意,LogUtil 的使用是根据配置偏好创建一个 Logger,然后返回它,它有实例方法,比如 log4j,你可以有 ConsoleLog、FileLog、RemoteLog 等

于 2013-10-18T09:33:40.787 回答
0

Author of this class would probably want to build a fluent interface, explaining why getInstance would be hidden for other class's method calls and explaining the return type not being void.

Benefit of this would allow client to make the method calls cleaner:

LogUtil.init().logSomething("something").anotherMethod("text");

The whole reduced to one line so.

I'm not dealing with the "static" debate, since as Aaron said above, static is often often often not recommended since it breaks flexibility/extensibility and is anti-OO.

于 2013-10-18T09:39:26.643 回答