2

I saw someone writing a java LOG API like the code unerneath. The idea is that the Client does not have to invoke LogUtil.getInstance() every time. But my feelings are this is not idiomatic 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();
}

}

What are the arguments against such a design (making every method static)?

jack
  • 1,861
  • 4
  • 31
  • 52

4 Answers4

6

This is basically a variant of "global variables" and the problem is always the same: You can have only one of them. If you ever need to replace or extend this, lot of code will break.

Which why other logging frameworks use factories:

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

That way, I have a single global variable (instead of dozens in your case). It's not ideal but give me at least a single point of failure.

This approach allows me to extend / replace the Logger interface with almost anything without having to change hundreds of places in my code.

That said: Don't write your own logging API. Use slf4j. It will take you a bit longer to understand how it works but many clever people have spent years to build a great logging framework that solves thousands of problems that you don't know about, yet.

EDIT

its not ecactly a general loging util. but more a "Reporter class" which produces Business Word documents.

Then have a look at static imports.

I would suggest to expose a single getInstance() method but give that method a more useful name. You can then import this single method statically everywhere else and call it without the LogUtil. prefix.

Aaron Digulla
  • 321,842
  • 108
  • 597
  • 820
  • its not ecactly a general loging util. but more a "Reporter class" which produces Business Word documents. The author argues that there will never be an extension or refactor of this LogUtil class. the author just wants to make the usage for the calling client code as easy as possible. There will also never be any threading problems – jack Oct 18 '13 at 09:50
  • The author if wrong. Every program that is in actual use will need extension and refactoring eventually. Don't save a few minutes by shooting future-you (or future-employee-who-has-to-maintain-your-code) in the foot. – Joachim Sauer Oct 18 '13 at 09:55
  • @jack: This is an approach that was used in structured programming (what we had before OO). Java, as an OO language, is somewhat inflexible when it comes to get rid of all the OO stuff. I would suggest to expose a single `getInstance()` method but give that method a more useful name. You can then import this single method statically everywhere else and call it without the `LogUtil.` prefix. – Aaron Digulla Oct 18 '13 at 11:32
0

static classes are Helper classes, for your LogUtil static class i would declare all methods to return 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;
}
}

But I'm not comfortable with that design, the use of a LogUtil is to create a Logger depending on configuration preferences, and return it, which have instance methods, like log4j you can have ConsoleLog, FileLog, RemoteLog, etc

RamonBoza
  • 8,898
  • 6
  • 36
  • 48
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.

Mik378
  • 21,881
  • 15
  • 82
  • 180
  • right exactly the author really prefers the fluent interface. he argues that having to call LogUtil.getInstance() is just much if you have to do this hundreds of times over and over. – jack Oct 18 '13 at 09:47
  • 1
    For people admitting that static methods are a good choice... he's right. For others, creating a factory returning a specific log instance for a specific class is more OO-focus. – Mik378 Oct 18 '13 at 09:48
0

One rule-of-thumb for making method static is: ask yourself "does it make sense to call this method, even if no Obj has been constructed yet?" If so, it should definitely be static." In your example, operations like logSomething(), anotherMethod() are doing something with instance. Since these methods don't make sense without instance, they should be non-static. Only getInstance() method should be static.

Main disadvantage of making everything static is you cannot swap, override or choose method implementations at runtime. This thread has good discussion on disadvantages of static: In Java, is there any disadvantage to static methods on a class?.

Community
  • 1
  • 1
drop.in.ocean
  • 298
  • 2
  • 9