Suppose you are developing an android app. You have created an AppDatabase class which performs all database logic (insertion, deletion, update, loading data from database etc) in the whole app.

Now, assume you have around 30-35 classes in your app where you need database operation.  In every class you have created a new AppDatabase object to use some of its methods.

AppDatabase appDatabase = new AppDatabase(context.getApplicationContext());

So, you are creating 30-35 AppDatabase objects in the whole app which are indifferent to each other. You are using unnecessary memory from system by creating same identical object again and again in the whole app. If your app grows more and more, you may need to create more AppDatabase objects in the app which will cause more memory usage of the system.

Now the question comes in mind, how can we avoid creating same identical object again and again? Okey, we can simply create a single object and use it everywhere. This is the concept of Singleton Design Pattern which ensures to create only one instance of an object.

public class AppDatabase {
	
    private static AppDatabase INSTANCE;
    
    private AppDatabase(Context context) {
    	//...
    }
    
    public static AppDatabase getInstance(Context context) {
    	if(INSTANCE == null) {
            synchronized (AppDatabase.class) {
                if (INSTANCE == null) {
                    INSTANCE = new AppDatabase(context);
                }
            }
        }
        return INSTANCE;
    }
    
}

Here, we have a private static variable INSTANCE and a private constructor. The constructor is kept private so that no other class can create an instance of AppDatabase.  In the getInstance method,  we check if an  INSTANCE has already been created. If not created then we create an instance of AppDatabase and return it. Otherwise we simply return the INSTANCE. We will use this static getInstance method in the whole app where we need the AppDatabase object. Therefore we can ensure of creating only one instance of AppDatabase object in the app.

We have used synchronized block to create an INSTANCE. This is done for thread safety. If two thread call the getInstance method at the same time and both of them get the INSTANCE as null, then they will create two different AppDatabase object which will break the principle of Singleton Pattern.

Now, when we need the AppDatabase object in any class, we will do the following :

AppDatabase appDatabase = AppDatabase.getInstance(context.getApplicationContext());

The getInstance method ensures of creating only one AppDatabase object.

That's all.