Venkata Subbarao
Venkata Subbarao

Reputation: 420

How to avoid singleton?

I have 6 classes as shown in the image below. I want all of these to be instantiated only once and at the same time, I would like to avoid singletons. Info class object will be created first in the application which reads the information of the system from a file. After this objects A, B, and C need to be created based on the info. After this Server1 and Server2 objects need to be created. Server1 objects want to access A object and Server2 wants to access A, B, C and Server1 objects.

Class heirarchy

How to solve this problem without using the singleton?

Thanks!
Subbarao

Upvotes: 1

Views: 2755

Answers (3)

Nick Bedford
Nick Bedford

Reputation: 4435

You could create normal classes then due to the usage architecture of your classes, only one instance of each class should ever reasonably be created. This is using dependency injection to replace singletons.

Some factory/main-like method would handle the loading/creation and passing of these instances to each of their dependents. No instance should ever need to exist as a singleton instance, but rather as a variable within a function.

// No need for singleton patterns,
// but only one instance is ever created
// by the program's main function.
int main()
{
    Info info = Info::LoadFromSystem("info.xml");

    A a = A::CreateFromInfo(&info);
    B b = B::CreateFromInfo(&info);
    C c = C::CreateFromInfo(&info);
    
    // dependency injection (use pointers or references, same essential thing)
    Server1 server1 = new Server1(&a); 
    Server2 server2 = new Server2(&server1, &a, &b, &c);

    server1.Run();
    server2.Run();

    // cleanup
    return 0;
}

Meeting Singletons Halfway

A common pattern often used in frameworks is the "default instance" style of singleton. This frees up the class to be reinstantiated for other simultaneous use but creates a default instance that can be relied upon for most cases.

In C++, the example might be like this, although it creates a requirement to handle shutdown of the app and destroy the default instance:

class MostlySingle
{
private:
    static MostlySingle *_default = NULL;

public:
    static MostlySingle *createDefault(Info &info) {
        if (_default != NULL) {
            // throw exception
        }
        _default = new MostlySingle(info);
        return _default;
    }

    static MostlySingle *default() {
        return _default;
    }

    static void destroyDefault() {
        delete _default;
        _default = NULL;
    }
}

int main()
{
    // app startup
    MostlySingle::createDefault(Info::default());

    auto instance = MostlySingle::default();
    instance.send("Hello, world!");

    // app shutdown
    MostlySingle::destroyDefault();
    return 0;
}

Upvotes: 0

Yola
Yola

Reputation: 19019

If you want an object to be created only once, then you need to count number of time it was created, otherwise there are always possibility that you or another programmer will accidentally create another instance. Usually that is done with the help of local static variable, and that is basically singleton.

Hard part is how to arrange access to your object across the program. That could be global variable, static method, or dependency injection that depends on your architecture. You can create all objects inside some class and then use getters to access them.

The bottom line is, that if your want to guarantee that the object can be created only once, then you are looking for some kind of singleton implementation.

Upvotes: 1

Germán Diago
Germán Diago

Reputation: 7663

Create them at the beginning of your program, remove the copy and move constructors from these classes and pass them down to the classes that depend on them. You can also make sure in the constructors that just an instance exists through a static class variable for each class incrementing a counter for a static variable. If it reaches 2, throw an exception. This way you will guarantee uniqueness.

Upvotes: 0

Related Questions