Confusion between singleton and Java static method

Suppose I want to implement a class that will provide me Connection

to connect to a database. I can implement the same thing with two different codes below.

Method 1:

class DBConnection1 {
    private static DBConnection1 instance = new DBConnection1();
    private DBConnection1(){

    }
    public static DBConnection1 getInstance(){
        return instance; 
    }
    public Connection getConnection(){
        Connection connection = null;
        //do my stuff to init the connection
        return connection;
    }
}

      

Method 2:

class DBConnection2 {
    public static Connection getConnection(){
        Connection connection = null;
        //do my stuff to init the connection
        return connection;
    }
}

      

And Accessing the above methods like

class TestConnection{
    public static void main(String[] args) {
        //using method 1
        Connection connection1 =  DBConnection1.getInstance().getConnection();
        //using method 1
        Connection connection2 =  DBConnection2.getConnection();
    }
}

      

I have little doubt which is better and why? What's the difference?

+3


source to share


6 answers


At a very high level, you can get confused and it looks like they both do the same thing. But there is a big difference. I answer this question in general. You can understand the benefits based on your application (type).

Singleton only stores shared data in one place. This will greatly simplify the architecture of the program and help you reuse code. Singletons allow you to more easily control the state of an object. This improves code exchange and code quality. Hence, it becomes easier to maintain. Singleton allows you to override if you want to override it. Lazy loading can be done using Singleton Classes. Singleton is more object oriented. Static objects are stored on the stack, while singleton objects are stored on the heap.



Static classes are hard to test compared to Singleton (Singleton is very easy to mock up. For example when using JUnit Tests). If you are using Spring or any such dependency injection framework, Singleton is better than static. A static class cannot be passed to a method or inherited. Static classes can create problems in a parallel environment due to shared data. its better not to maintain state in a static class. You can learn more about Singleton here http://en.wikipedia.org/wiki/Singleton_pattern or http://www.tutorialspoint.com/java/java_using_singleton.htm .

The only advantage I see with a static class is that it is faster. Use static ones only if a set of functions is to be stored together.

+3


source


Depends on what you are trying to achieve. For example, if you are sure that you will need this connection throughout the entire life cycle of the application, the static method is for you. But if you are not sure about this, use a singleton. But in real projects you probably shouldn't use static methods for anything other than some utils methods, because singleton is much more flexible than static methods.



But there is another pattern that you will probably be interested in. Including dependencies . It can be a little more complicated than the singleton, but again, it is much more flexible. The main thing is if in a large project you may need some of the functionality provided by the database and you will be using one class to access it. But later, the data is separated by two databases and two classes with the same interface, and instead, if you rewrite the code of the classes that use the database, you changed the implementation to be injected into the specific class. There are many more benefits to using Dependency Injection that I described, but I hope you succeed.

+2


source


These two alternatives are equivalent. However, I would prefer the singleton because it is easier in the future to replace the implementation or override the subclassing behavior.

Another point that will be more important is to create a new connection for each use or reuse of connection objects. This will go a long way in terms of prepared statements and commits / rollbacks.

+1


source


If you are planning on connecting a factory, it is better to implement method1. Because you can change the code inside you Factory with a little bump in the rest of the application.

A caveat when reusing a connection, as you might exchange context and it might be something you don't want!

Better to live ConnectionFactory

get from a connection pool, one connection, then use it, then release it, etc.

See Factory Pattern: If it's a Factory connection that serves connections, it's better to see Factory Method Pattern

+1


source


You are mixing two different patterns, namely Static Factory Method

(not the same as GoF Factory Method

) and Singleton

.

Static Factory Method is related to instantiation. The Singleton pattern is used to ensure that there is only one Singleton object.

eg. typical static Factory method:

public DBConnection {

    private DBConnection(String param) {
        //...
    }

    public static DBConnection createConnection(String param) {
        return new DBConnection(param);
    }

}

      

Note that usually a Factory method is called create...

or getNewInstance

or something similar to underline that this method will always return a new instance.

Same as Singleton:

public DBConnection {

    private static DBConnection instance;

    private DBConnection(String param) {
        //...
    }

    public static DBConnection getInstance() {
        if(instance == null){
            instance = new DBConnection("fixed param!");
        }
        return instance;
    }

}

      

Note that the same instance is always returned after it has been lazily created.

However, this picture can coexist - for example, a singleton can use a static Factory method to create an instance:

public DBConnection {

    private static DBConnection instance;

    private DBConnection(String param) {
        //...
    }

    public static DBConnection createInstance(String param) {
        return new DBConnection(param);
    }

    public static DBConnection getInstance() {
        if(instance == null){
            instance = DBConnection.createInstance("param");
        }
        return instance;
    }

}

      

I've intentionally left the static Factory method publicly available to highlight the difference between getInstance

and createInstance

here.

Also, constructors private

play an important role in these patterns, it ensures that methods createInstance

/ getInstance

should be used to get an instance.

+1


source


The short answer is that you shouldn't use the approach Singleton

. This is because you are returning a new connection

one every time the method is called getConnection

. If this is what you really want, there is no point in using a class Singleton

. Instead, you should go with method 2.

The long answer is that you seem to be confused about what really is Singleton

. The purpose of a class Singleton

is to ensure that there is only one object of a given class created for a given one ClassLoader

, thereby ensuring that the state of such an object is global. If your class does not contain state

, you can also use a class that contains only methods static

. Alternatively, if you are using a container IoC

like Spring

or Guice

, you can use Singleton

through a struct rather than explicitly creating your class like Singleton

. A class that is explicitly constructed like Singleton

but doesn't have any state really doesn't make much sense.

+1


source







All Articles