Skip to main content

SQL Problem - Find 3rd highest employee salary

Singleton Design Pattern

 

Singleton Design Pattern is one of the simplest creational design patterns. This design pattern ensures that class has only single instance initialized and by providing means to access the class instance.

In the many scenarios we need to restrict clients to allow creation of multiple instances of the class. This design pattern can be used when,

  • Creation of the object for each request is costlier. 
  • Class has the shared state of the global variables used across the application.
  • You don't want to have code that solve one problem that scatters across multiple classes.

Few common scenarios where we can see this design pattern are followed:

  • Create single connection to the database across application.
  • Maintain single truth of source for user state.
  • Global configuration of the application

How to implement Singleton Desing Pattern?

  1. Restrict the creation of class instance outside the class by making constructor private.
  2. Add static private global variable in the class of the same class type.
  3. Create public static method which check state of class instance variable and return after initializing if required.
In this blog let us take example of Database Connection class and implement using Singleton Design pattern with various approach and understand Prons and cons of each approach.


Simple Approach
In this approach we follow above mentioned simple steps to implement singleton design pattern using lazy initialization of the class instance.

package com.techtalesonline.designpattern.singletone;

public class DBConnection {
    // Create static class variable of the same class
    private static DBConnection dbCon;

    /**
     * Private constructor restrict creation of the object outside
     * of the class.
     */
    private DBConnection(){

    }
    /**
     * This static method creates instance of the class if it null and return.
     */
    public static DBConnection getInstance(){
        if(dbCon == null){
            dbCon = new DBConnection();
        }

        return dbCon;
    }
}

Prons:
  • Easy implementation
  • Lazy object creation
Cons:
  • It is not thread safe in multi-threaded environment.

Eager initialization Approach

In this approach we are creating instance of the class using static class variable. JVM will ensure that single instance of the class is created when class is loaded in the memory. This approach solves the problem of thread safety and ensure always there is single instance of the class.

package com.techtalesonline.designpattern.singletone;

public class DBConnection {
    // Create private static class variable of the same class
    private static DBConnection dbCon = new DBConnection();

    /**
     * Private constructor restrict creation of the object outside
     * of the class.
     */
    private DBConnection(){

    }
    /**
     * This static method creates instance of the class if it null and return.
     */
    public static DBConnection getInstance(){
        return dbCon;
    }
}

Prons:
  • Easy implementation
  • Eager initialization of the class instance
  • Thread safe as instance of the class is created while class loading.
Cons:
  • Waste of the resource if instance is not used in the application.
  • Slow application startup if there are many classes with singleton design pattern implementation.
  • Unable to pass parameters during initialization of the instance.
  • Exception handling is not possible.

Lazy Initialization with Thread safe Approach

In this approach we go with lazy initialization of the class instance using class method. This method is marked with synchronized to resolve thread safety issue. This will ensure that only one thread get lock for class and execute method. 

package com.techtalesonline.designpattern.singletone;

public class DBConnection {
    // Create private static class variable of the same class
    private static DBConnection dbCon;

    /**
     * Private constructor restrict creation of the object outside
     * of the class.
     */
    private DBConnection(){

    }
    /**
     * This static method creates instance of the class if it null and return.
     */
    synchronized public static DBConnection getInstance(){

        if(dbCon == null){    
            dbCon = new DBConnection();                    
        }
        return dbCon;
    }
}

Prons:
  • Resolve the thread safety issue.
  • Lazy initialization of the instance reduces memory wastage.
Cons:
  • Add the overhead of wait time when multiple thread tries to access method.

Lazy initialization with Double check locking

In this approach we are making only critical section of the code as synchronized plus adding double check before creating new object, so object creation reduces wait time when multiple thread tries to access create instance method. This is achieved through synchronized code block.

package com.techtalesonline.designpattern.singletone;

public class DBConnection {
    // Create private static class variable of the same class
    private static DBConnection dbCon;

    /**
     * Private constructor restrict creation of the object outside
     * of the class.
     */
    private DBConnection(){

    }
    /**
     * This static method creates instance of the class if it null and return.
     */
    public static DBConnection getInstance(){

        if(dbCon == null){
            synchronized(DBConnection.class){
                if(dbCon == null){
                    dbCon = new DBConnection();
                }
            }
           
        }
        return dbCon;
    }
}

Drawback of the Singleton Pattern

  • This design pattern violet Single Responsibilities Principle as it tries to solve two problems.
  • Difficult to perform unit testing.
  • This design pattern needs special attention in the multi-threaded environment.

Comments

Popular posts from this blog

SQL Constraints In DBMS

  Do we need constraints? SQL Constraints are set of rules and restrictions which are applied to the columns or table of the database. This constraint ensures below points. Data consistency No accidental data loss by deleting reference data. Reduce data redundancy. Table Level Constraints PRIMARY KEY FORIEGN KEY PRIMARY KEY Primary Key constraint ensure that column doesn't contain NOT NULL value and unique. It will be used to identify particular row from the table. Table is by default index on the primary key column. Below sample code creates EMP_ID as primary key for EMPLOYEE table which is auto increment by one every time a new record inserted in the table. CREATE TABLE EMPLOYEE (     EMP_ID INT PRIMARY KEY AUTO INCREAMENT NOT NULL ,     NAME   VARCHAR ( 200 ),      EMAIL VARCHAR ( 200 ), AGE INT,     PHONE_NUMBER VARCHAR ( 15 )     ISACTIVE CHAR ( 1 ) ) FOREIGN KEY Foreign Key is used to relate two tables. Th...

Different Keys In DBMS

Do we need key? DBMS (Database Management System)   stores large amount of data in such a way so that it will be easy to read, write and secure in efficient manner. It uses table format to organize data and store data in column and row format. However, data is stored in unordered format and difficult to identify unique record from the table. Let us understand this concept with two simple tables which represent data about the employees and their respective department. Employee Table Code Name Email Address Dept. Code Phone Number Address 01 John Smith j.smith@example.com 3 123-456-7890 123 Main St, City, Country 02 Jane Doe j.doe@example.com 1 987-654-3210 456 Elm St, City, Country 03 David Johnson d.johnson@example.com 2 555-123-4567 789 Oak St, City, Country ...

SQL Problem - Find 3rd highest employee salary

Problem Statement Create an SQL query to retrieve all details of employees who receive the third-highest salary. Ensure the query returns all columns from the employees table. Additional Requirement: Do not use the LIMIT keyword in your query. Sample Input: Table: employees: Sample Output Solution: Approach 1: Using Sub Query: select * from employees where salary = ( select distinct ( salary ) from employees   order by salary desc limit 1 offset 2 ) The subquery finds the third-highest distinct salary by ordering the salaries in descending order, skipping the first two, and then selecting the next one. The main query then retrieves all employees who have this third-highest salary. Approach 2: Using Nested Inner Queries SELECT * FROM EMPLOYEES WHERE SALARY = (     SELECT MAX ( SALARY ) FROM EMPLOYEES WHERE SALARY < (         SELECT MAX ( SALARY ) FROM EMPLOYEES WHERE SALARY < (           ...