0

I want to create one object per class type, like for example the Logger class of Apache that creates a new Logger instance if there is no instance for your class otherwise it gives you a new one.

I am thinking of this kind of class factory:

public class Logger {

    private String TAG;//the class name   
    private static HashMap<String, Logger> loggerList = new HashMap<String, Logger>();

    private Logger(String className){
        TAG="["+className+"]";
    }

    public static Logger getLogger(String className){
        Logger logger= loggerList.get(className);
        if( logger != null){
            return logger;
        }else{
            logger= new Logger(className);
            loggerList.put(className, logger);
            return (logger);
        }       
    }

I don't know if this is the best way to do it. Is there another way more optimised?

fabian
  • 80,457
  • 12
  • 86
  • 114
sabrina2020
  • 2,102
  • 3
  • 25
  • 54
  • 9
    Are you looking for the [Singleton Pattern](https://www.google.co.in/webhp?sourceid=chrome-instant&ion=1&espv=2&ie=UTF-8#q=singleton%20pattern)? – TheLostMind Oct 26 '15 at 10:22
  • 1
    Or possibly its brother, the Multipleton Pattern. – Kayaman Oct 26 '15 at 10:23
  • 2
    http://stackoverflow.com/questions/11126866/thread-safe-multitons-in-java – assylias Oct 26 '15 at 10:25
  • One for http://codereview.stackexchange.com/ ? – Brian Agnew Oct 26 '15 at 11:54
  • The apache logging source is here: http://svn.apache.org/viewvc/logging/log4j/trunk/src/main/java/org/apache/log4j/ If you want to see how that one works. – weston Oct 26 '15 at 12:06
  • Why static final field in the class does not work for you? – vrudkovsk Oct 26 '15 at 15:00
  • The Multiton Pattern is what I need, I guess I was using it without known it is name, I will take a look on the apache logging source also. Thanks every body. – sabrina2020 Oct 27 '15 at 08:14
  • @vrudkovsk : I want to prevent the instantiation on the Logging class side, I can use the static final field on my class but in case someone else want to add another class that uses my Logging class, he may forget to add "static final", thanks. – sabrina2020 Oct 27 '15 at 08:16
  • @sabrina2020 Why someone else would want to use your class? Are you trying to create yet another wrapper over logging framework? Slf4j is an answer. – vrudkovsk Oct 29 '15 at 11:20

1 Answers1

0

How about separating Logger out so that it doesn't have tag:

public interface Logger {
    void log(String tag, String message);
}

public enum DefaultLogger implements Logger {
    INSTANCE;
}

And Log Writer that does:

public class LogWriter {
    private final String tag;
    private final Logger logger;

    public LogWriter(String tag, Logger logger) {
        this.tag = tag;
        this.logger = logger;
    }

    public static forClass(Class clazz, Logger logger) {
        return new LogWriter("["+ clazz.getName() +"]", logger);
    }

    public static forClass(Class clazz) {
        return forClass(clazz, DefaultLogger.INSTANCE);
    }

    public void write(String message) {
       logger.log(tag, message);
    }
}

Usage:

LogWriter log = LogWriter.forClass(A.class);
log.log("ABC");

Then you create a LogWriter per instance, because why not, they are light, or store them in statics inside class if you really must reuse them:

public class A {
    private final static LogWriter log = LogWriter.forClass(A.class);
}
weston
  • 54,145
  • 21
  • 145
  • 203
  • This will create new loggers for same class when called with same arguments to `forClass`. Author wants the code to lazily initialize loggers by the class name, not construct new ones each time. – bezmax Oct 26 '15 at 11:52
  • @bezmax I know, I have added how you would achieve that too. – weston Oct 26 '15 at 11:53
  • `Then you create a LogWriter per class, or store them in statics inside class if you really must reuse them` - this is not what Author asked. He asked specifically for implementation similar to other logging frameworks, where each time you call `getLogger(MyClass.class)` it either loads a cached logger or creates new one. That's why hist original code has `HashMap` at all. – bezmax Oct 26 '15 at 11:54
  • @bezmax I don't like their approach of central caching. I can't/won't contribute to an approach I think is flawed. I will offer an alternative. – weston Oct 26 '15 at 11:57
  • `like for example the Logger class of Apache that >> creates a new Logger instance if there is no instance for your class otherwise it gives you a new one<< ` - here it is – bezmax Oct 26 '15 at 11:59
  • @bezmax yeah, I don't understand. If they like that, why don't they just look at the source and see how it works. – weston Oct 26 '15 at 12:00
  • @sabrina2020 Was this any help to you? Please upvote or accept helpful suggestions. – weston Jan 03 '17 at 23:12