Java – Creating a singleton to access static data

configurationdatajavasingleton

I have some properties in a property file that I referenced in a singleton so that I can access them easily from different parts of my application. For each property, I put the properties along with some additional information for each property in a list of objects. I'm doing this in the singleton's private constructor. Is this the correct way to store/access static data on a server?

Any help or guidance is appreciated.


Added example of what I'm currently doing

public class PropertiesSingleton {

    private static PropertiesSingleton instance = null;
    private List<MyPropertyObject> properties = new ArrayList<>();

    private static PropertyManager pm = PropertyManager.getInstance();

    private PropertiesSingleton() {
        properties.add("first property description", 
                "other property info", 
                new MyPropertyObject(pm.getProperty("firstProperty")));
        properties.add("second property description", 
                "other property info", 
                new MyPropertyObject(pm.getProperty("secondProperty")));
        properties.add("third property description", 
                "other property info", 
                new MyPropertyObject(pm.getProperty("thirdProperty")));
    }

    public static getInstance() {
        if (instance == null) {
            instance = new PropertiesSingleton();
        }
        return instance;
    }

    public getProperties() {
        return this.properties;
    }
}

Best Answer

If it works for you, then in that sense it is correct.

In a broader sense, I think a lot of people would see it as a kind of anti-pattern if you were using it in the following fashion:

class Foo
{
    public void Bar()
    {
        int value = StaticData.getInstance().getUsefulPropertyValue();
        // do stuff with value
    }
}

This is considered an anti-pattern because the fact that Foo depends on StaticData is hidden within Foo's implementation. This tightly couples Foo and StaticData. In this specific situation it may not be that big of a problem because StaticData is unchanging, but in the general situation this makes it harder to test the parent class.

For example, if Foo was actually depending on the singleton DatabaseAccess then unit testing Foo would be impossible. Foo would require the presence of a database to be tested which is a) inconvenient, and b) no longer technically a unit test!

You can get around this by using Dependency Injection:

class Foo
{
    private DatabaseAccess databaseAccess;

    // Here we use Constructor Injection to inject Foo's dependencies into it.
    // NOTE: The dependency on DatabaseAccess is made explicit by being a part of Foo's constructor signature.
    // This makes it clear that Foo cannot be created without an instance of DatabaseAccess.  It therefore depends on it.
    public Foo(DatabaseAccess databaseAccess)
    {
        this.databaseAccess = databaseAccess;
    }

    public void Bar()
    {
        // NOTE: We are no longer plucking its dependency out of thin air!
        int data = this.databaseAccess.getTheCoolestIntegerEver();
    }
}

Functionally, this code is very similar, but in terms of testability and maintainability it is far superior.

Also, note that DatabaseAccess may still very well be a singleton. The key take-away here is to never access your singletons with a static getInstance() method.