use of singleton design pattern in real time java applications - java

I understand the singleton design pattern concept, but I never really come across implementing singleton pattern in java applications or web based applications.
So tell me where we are using this approach in real time applications.

As described by the pattern, any time you want there to exist only a single instance of something, you would use the Singleton Pattern.
A common example might be a Logger object. There could be many places throughout the system where one would invoke a logger to, well, log something. But you may only ever need one such instance. This can be particularly true if constructing the instance is a heavy operation.
Something like this:
public class Logger {
private static final Logger INSTANCE = new Logger();
private Logger() {
// do something to initialize the logger
}
public static Logger getInstance() {
return INSTANCE;
}
// implementation ...
}
Then any code which needs to reference the logger doesn't need to instantiate it (can't, in fact), and instead just uses the singleton:
Logger.getInstance().Log("some message");
Other real-world examples might include a dependency injection container, a read-only data access service (such as a lookup service which caches results), etc. Generally anything where initialization or repeated operations can be heavy and which is thread-safe.

Singleton always makes sense when dealing with heavy objects where it makes no sense to have more than one instance across the whole application.
Since you are dealing with Web-Applications you should have been dealt with objects which are the same for each user/session/request. Database-Connection-Pool is probably a good example, or a Servlet. It doesn't make sense to create a new Pool for each request. One Pool for the whole application should be sufficient. Other examples are probably Loggers, Email-Client, Global-Settings, those things should be the same instances for each user otherwise you will run out of resources. Or did i get something wrong?

Related

Using dependency injection (via Guice) in a multi-module environment

I have a slight dilemma involving Guice and avoiding non-Guice singletons. Consider a multi-module project where there are 3 modules: shared, frontend and backend. Both the frontend and the backend use an instance of a Profiling class inside of the shared module (which times methods, and is used extensively throughout the project).
Almost every single class requires the use of this Profiling instance (including User objects created dynamically when a user connects).
If every single class requires an instance of the Profiling class, there are drawbacks to different methods of doing it:
Solution 1 (in the constructor, copied to the instance field):
private final Profiling profiling;
#Inject
public User(Profiling profiling, String username)
Drawback: You have to include a Profiling object in every single constructor. This is cumbersome and slightly pointless. You also have to store Guice's Injector statically (or inject it) so that you can create the User objects on-the-fly and not just when the program is first loaded.
Solution 2 (as a instance field only):
#Inject
private Profiling profiling;
public User(String username)
Drawback: Similar as above, you have to use Guice's Injector to instantiate every single object. This means that to create User objects dynamically, you need an instance of the Injector in the class creating the User objects.
Solution 3 (as a static field in one (main) class, created manually by us)
public static final Profiling PROFILING; // Can also use a get method
public Application() {
Application.PROFILING = injector.getInstance(Profiling.class)
}
Drawback: Goes against Guice's/dependency injection recommendations - creating a singleton Profiling object which is accessed statically (by Application.PROFILING.start()) defeats the purpose of Guice?
Solution 4 (as a static field in every single class, injected by Guice)
#Inject
private static Profiling profiling;
// You need to request every single class:
// requestStaticInjection(XXXX.class)
Drawback: Again, this goes against Guice's/dependency injection recommendations because it is statically injecting. I also have to request every single class that Guice needs to inject the Profiler into (which is also cumbersome).
Is there any better way to design my project and avoid falling back to the singleton design patterns I used to use?
TL;DR: I want to be able to access this Profiling instance (one per module) across every single class without falling back to singleton design patterns.
Thanks!
Pragmatically, I would use a normal singleton, maybe through a single-field Enum or a similar pattern.
To see why, you should ask the question: What is the purpose of Guice, and of dependency injection in general? The purpose is to decouple the pieces of your application so they can be independently developed and tested, and centrally configured and rearranged. With that in mind, you need to weigh the cost of coupling against the cost of decoupling. This varies based on the object you're choosing to couple or decouple.
The cost of coupling, here, is that you would be unable to operate any piece of your application without a real working instance of Profiling, including in tests, including for model objects like User. Consequently, if Profiling makes any assumptions about its environment—the availability of high-resolution system timing calls, for instance—you will be unable to use classes like User without allowing Profiling to be disabled. Furthermore, if you want your tests to profile with a new (non-Singleton) Profiling instance for the sake of test isolation, you'll need to implement that separately. However, if your Profiling class is lightweight enough not to pose a huge burden, then you might still choose this way forward.
The cost of decoupling is that it can force every object to become an injectable, as opposed to a newable. You would then be able to substitute new/dummy/fake implementations of Profiling in your classes and tests, and reconfigure to use different Profiling behavior in different containers, though that flexibility may not have immediate benefits if you don't have a reason to subsitute those implementations. For classes like User created later, you would need to pursue factory implementations, such as those provided through Guice assisted injection or AutoFactory code generation. (Remember that you can create an arbitrary number of objects by injecting Provider<T> instead of T for any object you would otherwise inject, and that injecting a Factory instance would be like customizing a Provider to take get parameters you choose.)
Regarding your solutions:
Solutions 1 and 2, per-object injection: This is where a Factory would shine. (I'd favor constructor injection, given the choice, so I'd go with solution 1 between them.) Of course, everything that creates a new User would need to instead inject a User.Factory, so that may turn a tightly-scoped project into a project to convert every class in your codebase to DI—which may be an unacceptable cost for what you're trying to do now.
// Nested interface for your Factory:
public interface Factory { User get(String username); }
// Mark fields that the user provides:
#Inject public User(Profiling profiling, #Assisted String username) { ... }
// Wire up your Factory in a Module's configure:
install(new FactoryModuleBuilder().implement(User.Factory.class));
// Now you can create new Users on the fly:
#Inject User.Factory userFactory;
User myNewUser = userFactory.get("timothy");
Solution 3, requesting static injection of a main holder approximates what I had in mind: For the objects not created through dependency injection, request static injection for a single class, like ProfilingHolder or somesuch. You could even give it no-op behavior for flexibility's sake:
public class ProfilingHolder {
// Populate with requestStaticInjection(ProfilingHolder.class).
#Inject static Profiling profilingInstance;
private ProfilingHolder() { /* static access only */ }
public static Profiling getInstance() {
if (profilingInstance == null) {
// Run without profiling in isolation and tests.
return new NoOpProfilingInstance();
}
return profilingInstance;
}
}
Of course, if you're relying on calls to VM singletons, you're really embracing a normal VM-global static singleton pattern, just with interplay to use Guice where possible. You could easily turn this pattern around and have a Guice module bind(Profiling.class).toInstance(Profiling.INSTANCE); and get the same effect (assuming Profiling can be instantiated without Guice).
Solution 4, requestStaticInjection for every single class is the only one I wouldn't consider. The list of classes is too long, and the likelihood that they'll vary Profiling is too slim. You'd turn a Module into a high-maintenance-cost grocery list rather than any sort of valuable configuration, and you'd force yourself into breaking encapsulation or using Guice for testing.
So, in summary, I'd choose Guice singleton injection for your current injectable objects, normal singleton for your current newable objects, and the option of migrating to Factories if/when any of your newables make the leap to injectables.

Java Singleton Class Behaviour in Multi Threaded environment

I have read many stackoverflow questions on this but phrased differently and not answered what I was looking for. I don't expect any code solutions but a behavioral explanation of singleton object in multi-threaded environment. Answers with some links with explanation would be great.
Question 1:
If there are multiple thread that needs to access singleton object(say configured as singleton bean in spring config), then is it that only one thread is able to get access and others are blocked till current holding thread releases it.
For me blocking here makes sense, because there is only one object and all threads cannot get same object at the same time.
So if I configure my DAO as singleton bean then if multiple users(threads) try to do reads and write through that DAO then it doesn't actually happen concurrently but sequentially ---> a performance issue in database intensive application.
On the other hand most of the DAOs are stateless(atleast in my case), so instead of configuring it as Singleton, I can instantiate it wherever I need and do the operations concurrently, but each object instantiation may take some time and memory. So it is a design decision.
In my case, since DAO has no state variable so memory would be negligible, so if my above theory is correct then I would go with 2nd option i.e. choosing concurrency over memory.
Question 2: For the question asked here
I think the best answer is below by S.Lott(I don't know how to point link
directly to the answer so copying the answer):
Singletons solve one (and only one) problem.
Resource Contention.
If you have some resource that
(1) can only have a single instance, and
(2) you need to manage that single instance,
you need a singleton.
Here my question is if above answer is true--> That would be the reason for loggers implemented as singletons because you have one log file(single resource).
You don't want that due to time slicing if one thread has written part of some log into the file and then suspended and then thread-2 writes its part and then thread-1 again, thereby making log file gibberish.
I stroke above text because I think if one thread is logging then second thread cannot log at all(blocked) because of singleton config, there by avoiding making log file a gibberish.
Is my understanding right?
"Singleton" has no meaning in the Java programming language. It's just a design pattern. The behavior of a singleton object that is shared by many threads is no different from the behavior of any other object that is shared by many threads.
It's safe if, and only if, you make it safe.
The quote you have is correct but incomplete. Singleton have more purposes, which hopefully becomes clear later on.
The answer to your first question is, it depends on the bean and how it is implemented. Instances instantiated by Spring do not guarantee thread-safety. For the purpose of answering this question, suppose that there are two possible categories of implementations: stateful and stateless. An implementation can be considered stateful if there are any methods that require external resources (e.g. field variables, database access, file access) that are mutable. On the other hand, an implementation is stateless if all the methods are able to execute their tasks using only their parameters and immutable external resources.
class Stateful {
private String s; // shared resource
void setS(String s) {
this.s = s;
}
}
class Stateless {
int print(String s) {
return s.size();
}
}
Now, if the implementation is stateless, it generally makes sense for it to be a singleton. Because a stateless class is inherently thread-safe. Multiple threads can use the methods concurrently (without blocking). Just because a class is stateless does not mean that it consumes negligible memory. In Java, instantiating a class is considered an expensive operation.
More work is required for stateful implementations to be a singleton. Again for the purpose of answering this question, suppose that there are two categories of implementation: blocking and non-blocking. Blocking is as described (although there are various types of blocking). Non-blocking means that multiple threads can call the methods concurrently. Typically, there is a thread specially for the non-blocking implementation for processing.
Loggers are good examples of non-blocking implementations. Below is a highly simplified code.
class Logger {
private List<String> msgs = new CopyOnWriteArrayList<>();
void log(String msg) {
msgs.add(msg);
}
private void process() {...} // used internally by a thread specially for Logger
}
As for question 2, the basic answer is no; singletons are not all bad. Design patterns are double-edge swords. Use them wisely and they improve your code; use them badly and they create more problems than they solve.
Whatever #james said is correct. Coming to your questions:
Question 1: Multiple threads can get access to singleton object without blocking unless you make the get method which returns the object synchronized. Please see below(Multiple threads can get a reference to singleton object without getting blocked).
public class Singleton {
private Singleton() {
}
private static class SingletonHelper {
private static final Singleton INSTANCE = new Singleton();
}
public static Singleton getInstance() {
return SingletonHelper.INSTANCE;
}
}
Question 2: No your understanding is incorrect. If one thread is writing, another thread must wait, this is not because of singleton config, but because there might be a possibility that the object(file) may end up in inconsistent state; same is applicable for any object not synchronized properly.
you are linking then singleton pattern and a multithread application assuming that the access to the singleton object must be serialized; this is not true.
The requirement is that the singleton must be thread safe.
Consider the DAO example in your question; assuming the each invocation is stateless (i.e. you don't share variables within the class but only witihin the methos) you don't need multiple instance of the same DAO, in a Spring application usually there is one or more manager classes (usually you manage then DB transactions of these manager classes using AOP); each of them has a reference to a single DAO. Each time a DAO object is invoked it gets a DB connection form the data source and it executes the desired operation, then it releases the connection to the data source.
When multiple threads call your manager class you need to acquire/release the DB connection in a thread safe way. Usually Spring hides this complexity and you don't need to worry about that.
A pseudo code for the dao is something like
public void doSomeDBOperation(YourObject param) {
Connection connection=acquireDBConnection();//the connection must be acquired in a thread safe way
SQLStatement statement=connection.createStatement(yourSQL);
//do the operation with your param;
releaseDBConnection(connection);
}
Spring does sometinh similar under the hood it acquires a Db connection in the AOP aspect, it save in thread local variable so it ca be used by multiple DAOs and you can manage the transaction over the connection.
So one manager, one dao and multiple DB connections is a way to manage multithread operations in parallel (you serialize only the DBconnection lease/release assuming you are using a connection pool) and doing DB operation without blocking (at a java level on the db level things operations may lock in order to guarantee integrity constraints).
Regarding the logger question I assume you are refering to the way most logging library are used i.e you declare a static logger in each of you classes:
public class MyClass {
private static final Logger logger=LoggerFactory.get(MyClass.class.getName());
.....
}
The logger class and the file where you log are not directly linked, with Log4J, LogBack, etc you can log to multiple files with one log call, you can even log to something that is not file (a socket for example). The real writing operations are done by the appenders, the appenders must be thread safe and serialize the access to the underlying resource if needed. In you application you declare multiple loggers (one for each class) so there is one singleton per class not only one logger class in you application.
Different threads can invoke the same logger in paralled but it's the underlyng appender guarantees that the access to the underlyng file (o to something else) is serialized if needed (if you have an appender that sends a mail instead of writing a file you can do it concurrently).
If you want to combine multithreading and a single logfile that's not achieved by singletons, singletons only have influence in one thread to avoid another one from popping up.
Now if you break this by using multiple threads, singletons won't help you. If they did, the second thread would just be incapable of logging.

Good case for Singletons?

I have an application that has several classes used for storing application-wide settings (locations of resources, user settings, and such). Right now these classes are just full of static fields and methods, but I never instantiate them.
Someone suggested I make them Singletons, What's the case for/against?
I consider the Singleton pattern to be the most inappropriately applied design pattern. In ~12 years of software development I'd say I've maybe seen 5 examples that were appropriate.
I worked on a project where we had a system monitoring service that modeled our system with a System class (not to be confused with Java's built-in System class) that contained a list of Subsystems each with a list of Components and so on. The designer made System a Singleton. I asked "Why is this a Singleton?" Answer: "Well, there is only one system." "I know, but, why did you make it a Singleton? Couldn't you just instantiate one instance of a normal class and pass it to the classes that need it?" "It was easier to just call getInstance() everywhere instead of passing it around." "Oh..."
This example is typical: Singletons are often misused as a convenient way to access a single instance of a class, rather than to enforce a unique instance for technical reasons. But this comes at a cost. When a class depends on getInstance(), it is forever bound to the Singleton implementation. This makes it less testable, reusable, and configurable. It violates a basic rule I follow and that probably has a common name in some design principles essay somewhere: classes should not know how to instantiate their dependencies. Why? Because it hardcodes classes together. When a class calls a constructor, it is bound to an implementation. getInstance() is no different. The better alternative is to pass an interface into the class, and something else can do the constructor/getInstance()/factory call. This is where dependency injection frameworks like Spring come in, though they are not necessary (just really nice to have).
So when is it appropriate to use a Singleton? In that rare case where instantiating more than one of something would literally ruin the application. I'm not talking about instantiating two Earths in a solar system app - that's just a bug. I mean where there is some underlying hardware or software resource that will blow up your app if you call/allocate/instantiate it more than once. Even in this case, classes that use the Singleton should not know it is a Singleton. There should be one and only one call to getInstance() that returns an interface that is then passed to constructors/setters of classes that need it. I guess another way of saying it is that you should use a Singleton for its "singleness" and not for its "globally accessibleness".
By the way, on that project I mentioned where System was a Singleton... Well System.getInstance() was laced throughout the code base, along with several other inappropriate Singletons. A year later some new requirements came down: "We are deploying our system to multiple sites and want the system monitoring service to be able to monitor each instance." Each instance... hmmm... getInstance() ain't gonna cut it :-)
Effective Java says:
Singletons typically represent some system component that is intrinsically
unique, such as a video display or file system.
So if your component warrants single instance accross the entire application and it has some state, it makes sense to make it a singleton
In your case, the settings of the application is a good candidate for singleton.
On the other hand, a class can only have static methods if you want to group certain functions together, such as utility classes, examples in jdk are java.util.Arrays java.util.Collections. These have several related methods that act on arrays or collections
Singleton will give you an object reference, that you can use all over your app...
you will use singleton if you want objects and/or polymorphism...
If you don't ever need to instantiate them, I don't see the point of singletons. Well, I should amend that - if these classes cannot be instantiated, then it doesn't make sense to compare them to singletons - the singleton pattern restricts instantiation to one object, and comparing that to something that cannot be instantiated doesn't make sense.
I find my main use of singletons generally involves a class that has static methods that, after maybe preparing an environment, instantiate an instance of themselves. By utilising private constructors and overriding Object.clone() to throw CloneNotSupportedException, no other classes can create a new instance of it, or if they're ever passed an instance of it, they cannot clone it.
I guess I'd say that if your application settings are part of a class that is never instantiated, it's not relevant to say "It should/shouldn't be a singleton."
I think you no need to create signleton class.
just make this class constructor private.
Like Math class in java.
public final class Math {
/**
* Don't let anyone instantiate this class.
*/
private Math() {}
//static fields and methods
}
Singletons often show up in situations like you're describing- you have some sort of global data that needs to live in some place, and you'll only ever need one, preferably you want to make sure that you can only have one.
The simplest thing you can do is a static variable:
public class Globals{
public static final int ACONSTANT=1;
This is fine, and ensures that you'll have only one, and you have no instantiation issues. The main downside, of course, is that it's often inconvenient to have your data baked in. It also runs into loading issue if, for example, your string is actually built, by, say, building something from an outside resource (there's also a gotcha with primitives - if your static final is an int, say, classes that depend on it compile it inline, which means that recompiling your constants may not replace the constants in the app - e.g., given public class B{ int i = Globals.ACONSTANT; } changing Globals.ACONSTANT and recompiling only Globals will leave B.i still =1.)
Building your own singleton is the next simplest thing to do, and is often fine (though look up discussions on problems inherent in singleton loading, e.g. double-checked locking).
These sorts of issues are a big reason why many apps are built using Spring, Guice, or some other framework that manages resource loading.
So basically:
Statics
Good: easy to code, code is clear and simple
bad: Not configurable- you've got to recompile to change your values, may not be workable if your global data requires complex initialization
Singletons fix some of this, Dependency Injection frameworks fix and simplify some of the issues involved in singleton loading.
Since your class is holding global settings, a pro for a singleton could be that you have more control about creation of the singleton. You could read a configuration file during object creation.
In other cases if methods are static there would be no benefit like in javas Math class which has only static members.
A more obvious need for singletons is when you implement factories as singletons, because you can interchange different implementations of this factory.
Sometimes what people think belong as Singleton objects really can be private members of a class. Other times they should be unique global variables. Depends on what the design needs them to be.
If there should be one, and exactly one instance of an object: use a Singleton. By that, I mean if the program should HALT if there's more than one object. A good example is if you're designing a video game that only supports rendering to a single output device, ever. Trying to opening the same device again (shame on you for hardcoding!) would be forbidden. IMHO a case like that often means you shouldn't be using classes in the first place. Even C allows you to trivially encapsulating such a problem without the complexity of making a Singleton class, and still maintain the elements of OO that apply to a singleton. When you're stuck in a language like Java/C# , the singleton pattern is what you've got to work with, unless purely static members will do the trick on their own. You can still simulate the other way through those.
If it's merely a case of interfacing objects, you probably should think more object oriented. Here's another example: let's say our game engines rendering code needs to interface resource and input managers, so it can do it's job. You could make those singletons and do sth like ResourceManager.getInstance().getResource(name). Or you could create an application class (e.g. GameEngine) that has ResourceManager and InputManager as private members. Then have the GameEngine pass these as necessary to methods of the rendering code. Such as r.render(resourcemanager);.
For singletons—can easily be accessed from anywhere, it's like a global variable, but there can only be one copy of it.
Against singletons—many uses of singletons can be solved by encapsulating it within in a parent object and passing a member object to another member objects methods.
Sometimes just using a stupid global variable is the right thing. Like using GOTO or a compounded (and/or) conditional statement instead of writing the same error handling code N times with copy and paste.
Code smarter, not harder.
You should use singletons for modularization.
Imagine the following entities in singleton:
Printer prt;
HTTPInfo httpInfo;
PageConfig pgCfg;
ConnectionPool cxPool;
Case 1.
Imagine if you did not do that, but a single class to hold all the static fields/methods.
Then you would have one big pool of static to deal with.
Case 2.
In your current case, you did segregate them into their appropriate classes but as static references. Then there would be too much noise, because every static property is now available to you. If you do not need the information, especially when there is a lot of static information, then you should restrict a current scope of the code from seeing unneeded information.
Prevention of data clutter helps in maintenance and ensure dependencies are restricted. Somehow having a sense of what is or is not available to me at my current scope of coding helps me code more effectively.
Case 3 Resource identity.
Singletons allow easy up-scaling of resources. Let us say you now have a single database to deal with and therefore, you place all its settings as static in the MyConnection class. What if a time came when you are required to connect to more than one database? If you had coded the connection info as a singleton, the code enhancement would comparative much simpler.
Case 4 Inheritance.
Singleton classes allow themselves to be extended. If you had a class of resources, they can share common code. Let's say you have a class BasicPrinter which is instantiable as singleton. Then you have a LaserPrinter which extends BasicPrinter.
If you had used static means, then your code would break because you would not be able to access BasicPrinter.isAlive as LaserPrinter.isAlive. Then your single piece of code would not be able to manage different types of printers, unless you place redundant code.
If you are coding in Java, you could still instantiate a totally static content class and use the instance reference to access its static properties. If someone should do that, why not just make that a singleton?
Of course, extending singleton classes have their issues beyond this discussion but there are simple ways to mitigate those issues.
Case 5 Avoid information grandstanding.
There are so few pieces of info that needs to be made globally available like the largest and smallest integers. Why should Printer.isAlive be allowed to make a grandstand? Only a very restricted set of information should be allowed to make a grandstand.
There is a saying: Think globally, act locally. Equivalently, a programmer should use singletons to think globally but act locally.
Effective Java says:
Singletons typically represent some system component that is intrinsically
unique, such as a video display or file system.
So if your component warrants single instance across the entire application and it has some state, it makes sense to make it a singleton.
(The above nakedly borrowed from naikus)
In many cases the above situation can be handled by a 'utility class' in which all the methods are static. But sometimes a Singleton is still preferred.
The main reason for advocating a Singleton over a Static Utility Class is when there is a non-negligible cost involved in setting it up. For example if your class represents the file system, it will take some initialization, which can be put in the constructor of a Singleton but for a Static Utility Class will have to be called in the Static Initializer. If some executions of your app might never access the file system then with a Static Utility Class you have still paid the cost of initializing it , even though you don't need it. With a Singleton if you never need to instantiate it you never call the initialization code.
Having said all that, Singleton is almost certainly the most-overused design pattern.

Are there penalties for Enum Singletons?

Are there (performance) penalties* associated with the Enum Singleton Pattern in any way, as it seems to be used less than the classical singleton pattern or the inner holder class idiom?
* Penalties, such as the cost of serializability in cases when it is not needed and such, or is the usage low because few of the developers read Effective Java 2nd edition?
All Java singleton patterns (both this and the standard with private constructor and static accessor) have this bad property that if you to test them (or test anything that even remotely depends on them) can use this and only this object.
For example if you want to test PrintingService class that depends on PrintingSingleton you will not be able to replace this printing singleton with a mock because it is bound statically.
i.e. imagine testing this function
boolean printDocument(Document d) {
if (PrintingSingleton.INSTANCE.isPrinterEnabled()) {
PrintingSingleton.INSTANCE.print(d);
}
throw new RuntimeExeption("Printing not enabled");
}
with a test
#Test(expectedExceptions = {RuntimeException.class})
public void testPrinting() {
PrintingService service = ...
service.print(new Document()); // How will you simulate
// throwing an exception?
}
Personally, I would just avoid using singletons that way but rather introduce dependency injection, via Guice, Spring or Pico Container. That way you ensure existence of only one object, while not limiting yourself to not being able to mock the object out for example for tests.
You will not get any performance penalties for using an Enum-based singleton, as Enums are really just regular classes at runtime. I suppose you may get a very slight performance hit at classload time since the system may be doing all the correct initialization that are needed for correctness. There should be no cost to being Serializable, since that is just a tag interface, only check if you try to serialize. It really is the best known method for creating singletons!

Cons for defining logger non-static

Comments for this answer How do you reduce Java logging boilerplate code? strongly suggest not to use loggers as instance member variables. I can think of two negative side-effects:
1) superclass logs with the subclass's logger
2) object cannot be serialized (unless marked transient)
But if serializing is not necessary and logging with subclass name is not a problem, is there anything else why it should be avoided? I think it reduces boilerplate code and avoids copy-paste errors while copying logger variable definition from one class to another. Even Spring framework (which I believe has very good coding standards) uses this method.
If your Logger is an instance member instead of static, the Logger has to be retrieved every time a new object is created. Albeit this overhead is probably insignificant, but it's one disadvantage.
From a design perspective, Loggers aren't really a property of an object, since they're usually meta-information about your system rather than business information within the system itself. A Logger isn't really part of something like a Car object in the same way an Engine or a Transmission is. Tying Loggers to objects as members (in most cases) doesn't make sense semantically more than anything.
You might want to have a look at these pages discussing the subject:
SLF4j FAQ: Should Logger members of a class be declared as static?
Commons Wiki: When Static References to Log objects can be used
The major difference asides from the Superclass logging with subclass name, of course, is that you'll have one Logger object per member of your class. Depending on how many classes are using logging, this can be a huge amount of Loggers, so memory bloat may be an issue.
Plus from an abstract point of view, the logger really does belong to the class and can be shared between all instances, rather than each instance needing its own private copy, so it makes sense to declare it as static. Flipping your question around, what advantages does it have to making it non-static? (Being able to pass getClass() into the getLogger() call instead of passing in the class constant is the only thing I can think of, and that's such a tiny thing).
Another, probably minor con: wasted memory, especially when you have lots of instances, each one with its own logger
Try debugging an error where you see a message generated by the SuperClass class when the error is really being logged in the SubClass class. I've seen several situations where developers create a LoggingUtils class which generates messages which generally duplicate the things which are already baked-in by the logging framework.
The only real situation I see for using a shared logging instance is something like the Apache commons HttpClient logger httpclient.wire which is shared between several classes for logging the contents of the requests and responses sent through the client. This particular logging situation does not log information for the actual implementation of the package, it logs information about the whole http "transaction".
One of the main concerns are at cleaning memory instances. Even you don't create objects of a class, since you use static instances of logger there will be references to those objects.
Also as apache says, this keeps references so they won't freed once after used.
Apache Wiki says like this
The use of the static qualifier can be beneficial in some circumstances. However in others it is a very bad idea indeed, and can have unexpected consequences.
The technical result of using static is obvious: there is only one Log reference shared across all instances of the class. This is clearly memory efficient; only one reference(4 or 8 bytes) is needed no matter how many instances are created. It is also CPU-efficient; the lookup required to find the Log instance is only done once, when the class is first referenced.

Categories