Tag Archives: singleton

A BEGINNER’S GUIDE TO DEPENDENCY INJECTION!!

Heya people.!

In my last post I discussed about Singletons, its advantages and disadvantages, why it is considered an anti-pattern and stated DI as a better option.In this blog, I will be proving my statement along with going through DI basics and its key benefits.

But, to start with our discussion, we first need to understand the importance of DI.

For example, if we want to make tea for our guests. We will need to collect all the ingredients such as tea leaves, water, kettle , sugar and milk all by ourselves and then put the kettle on the gas to boil water, add tea leaves, milk and sugar and let the mixture boil before we serve it. For all this time, our guests will be waiting for us to get free and meet them. Will it then not be better to have a helping hand who knows better than us to make tea, who will make tea and serve us. If the latter solution excites you, then ladies and gentlemen, welcome to the world of DEPENDENCY INJECTION!

In the above example, if we take tea as an object, then DI help us in initializing the tea object and provide the object with all the necessary resources (i.e in our case ingredients). So basically, DI provides us with what an object needs to get initialized.

Dependency Injection is all about following 3 topics:

  1. Dependency Inversion Principle (DIP)]
  2. Inversion of Control (IOC)
  3. Dependency Injection

DEPENDENCY INVERSION PRINCIPLE

It is a software design pattern that states 2 principles:

  • High-level modules should not depend on low-level modules. They both should depend on abstractions.
  • Abstractions should not depend on details. Instead details should depend on abstractions.

To explain the above principle, let us take a very simple example.

Let us suppose, we have a watcher class that logs a message when it is notified about an event. The class will somewhat look like below:

class EventLog{
    public void log(String msg){
               //log message here
      }
 }

class Watcher{
        EventLog eventLog=null;

        public void notify(String msg){
        if(eventLog==null)
              eventLog=new EventLog();
        eventLog.log(msg);
    }
}

The example given shows no problem at first, but if looked closely violates DI principle. Let us know why!

In the above example, the high level class (Watcher class) depends on the low level class (EventLog class). Also, it depends on the concrete implementation of the low-level class, which completely violates both the principles of DIP.

Also, if at a later stage, requirement arises to extend the functionality of the watcher class i.e probably to send an email or a sms or both, to the designated person every time an event is logged, we’ll have to keep adding concrete implementations in the Watcher class. This will make the code coupled and unmanageable.

class EventLog{
      public void log(String msg){
              //log message here
          }
   }

class Email{

public void email(String msg){
     //email message here
  }
}

class Watcher{

     EventLog eventLog=null;
     Email email=null;

     public void notify(String msg){
     if(eventLog==null)
             eventLog=new EventLog();
      eventLog.log(msg);

     if(email==null)
            email=new Email();
     email.email(msg);
  }
}

Hence to avoid the above situation IOC was introduced.

INVERSION OF CONTROL

It is a mechanism using which we can make the higher level modules depend on abstractions rather than concrete implementations of lower level modules.

Basically we invert the control flow of our code to conform the DIP.

So, for the above example, we make all our concrete classes (EMAIL,SMS and EventLog) implement a common interface or abstract class CommInt consisting of a method actOnNotification().


abstract class CommInt{
       public abstract void actOnNotificstion(String msg);
}

class EventLog extends CommInt{
          public void log(String msg){
              //log message here
        }

     @Override
     public void actOnNotificstion(String msg) {
              log(msg);
     }
}

class Email extends CommInt{
        public void email(String msg){
              //email message here
      }

      @Override
      public void actOnNotificstion(String msg) {
            email(msg);
     }
}

class Watcher{
     CommInt commInt=null;
   
     public void notify(String msg){
       if(commInt==null)
          commInt=new EventLog();

       commInt.actOnNotificstion(msg);

       if(commInt==null)
          commInt=new Email();

        commInt.actOnNotificstion(msg);
    }
}

In the above example, although our concrete classes now depend on abstractions, still to create a concrete type and to assign it to this abstraction we, still have to create the object in our Watcher class, that takes us where we started.

Hence, our third and final topic DEPENDENCY INJECTION comes into play.

DEPENDENCY INJECTION

DI’s main motive is to reduce coupling between classes through injecting concrete implementations of a class that is using abstraction.

There are 3 ways to inject the same:

1. Constructor Injector: We pass the object of concrete class in constructor of dependent class. It is the most widely used.


public class Launcher {

 public static void main(String[] args) {
   Email email=new Email();
   Watcher watcher=new Watcher(email);
   watcher.notify("This Watcher class object sends email for its whole lifetime");

   EventLog eventLog = new EventLog();
   Watcher watcher1 = new Watcher(eventLog);
   watcher1.notify("This Watcher class object logs events for its whole lifetime");

   }
}

abstract class CommInt{
   public abstract void actOnNotificstion(String msg);
}

class EventLog extends CommInt{
   public void log(String msg){
      //log message here
   }

   @Override
   public void actOnNotificstion(String msg) {
     log(msg);
   }
}

class Email extends CommInt{
   public void email(String msg){
     //email message here
   }

   @Override
   public void actOnNotificstion(String msg) {
     email(msg);
   }
}

class Watcher{
   CommInt commInt=null;
   Watcher(CommInt commInt){
     this.commInt=commInt;
   }

   public void notify(String msg){
     commInt.actOnNotificstion(msg);
   }
}

It is useful when we know the instance of the dependent class and will us the same concrete class for its lifetime.

2. Method Injector: We pass object of concrete class into the method of dependent class.


public class Launcher {

  public static void main(String[] args) {
    Email email=new Email();
    Watcher watcher=new Watcher();
    watcher.notify(email,"This Watcher class object first sends email.");
    
EventLog eventLog = new EventLog();
    watcher.notify(eventLog,"and then logs events.!");
  }
}

abstract class CommInt{
  public abstract void actOnNotificstion(String msg);
}

class EventLog extends CommInt{
  public void log(String msg){
    //log message here
  } 

  @Override
  public void actOnNotificstion(String msg) {
    log(msg);
  }
}

class Email extends CommInt{
   public void email(String msg){
     //email message here
   }

    @Override
    public void actOnNotificstion(String msg) {
       email(msg);
    }
}

class Watcher{
      CommInt commInt=null;

      public void notify(CommInt commInt,String msg){
      this.commInt=commInt;
      commInt.actOnNotificstion(msg);
   }
}

It is useful when we need to pass separate concrete class on each invocation.

3. Property Injector: We pass object via a setter property that was exposed by the dependent class. It is used less frequently.


public class Launcher {

    public static void main(String[] args) {
        Email email = new Email();
        Watcher watcher = new Watcher();
        watcher.notify("This Watcher class object first sends email.");

        EventLog eventLog = new EventLog();
        watcher.set(eventLog);
        watcher.notify("and then logs events.!");

    }
}

abstract class CommInt {

    public abstract void actOnNotificstion(String msg);
}

class EventLog extends CommInt {
    public void log(String msg) {
        //log message here
    }

    @Override
    public void actOnNotificstion(String msg) {
        log(msg);
    }
}

class Email extends CommInt {
    public void email(String msg) {
        //email message here
    }

    @Override
    public void actOnNotificstion(String msg) {
        email(msg);
    }
}

class Watcher {

    CommInt commInt = null;

    public CommInt get() {
        return commInt;
    }

    public void set(CommInt commInt) {
        this.commInt = commInt;
    }

    public void notify(String msg) {
        get().actOnNotificstion(msg);
    }
}

It is useful when selection of concrete and invocation of method are in different places.

All the 3 injections are best for one level of dependencies. For a chained or nested dependencies, IOC containers (like Spring, hibernate, etc) come into play. These help us to map the dependencies easily when we have chained or nested dependencies.

KEY BENEFITS

  • maintainable code
  • de-coupled code
  • extendable code
  • move dependency resolution from compile time to run time.
  • centralized configuration
  • improves application testing

In our above example of watcher class,

  • We need to change our launcher to use Email class instead of SMS or EventLog class.
  • Independent unit cases can be created to test all the concrete classes with our Watcher class.

DRAWBACK

The main drawback of dependency injection is that using many instances together can become a very difficult if there are too many instances and many dependencies that need to be resolved.

DI better than Singletons

Singletons maintain a global state which is hard to test. Also, they cannot be extended i.e you can’t change the implementation used by one class without changing it for all of them. For the said reasons, DI will always be a better option! 😀

Hope, the basic concept regarding DI must’ve been cleared. !! For any queries, leave a comment.! 🙂

Understand Singletons at one go!

If you are looking for a switch and have 0-2 years experience in Java, then this is one topic that you must know. In this post, I try to explain all aspects of the topic and in the end include all possible questions asked.

Singleton Design Pattern is the most simple but most controversial pattern in terms of complexity of usage. It was basically introduced to solve the problem of allowing only one object to control some resource, and allowing only one copy of the object to exist i.e it provides global point of access to the object. Commonly used in logging, caches, thread pools, configuration settings, device driver objects, etc.

Singleton class control object creation, limiting the number to one but allowing the flexibility to create more objects if the situation changes.

STRUCTURE

Singleton Class Diagram

  • Static member : This contains the instance of the singleton class.
  • Private constructor : This will prevent anybody else to instantiate the Singleton class.
  • Static public method : This provides the global point of access to the Singleton object and returns the instance to the client calling class.

USAGE

Singletons must be used when only a single instance of object is required in memory for a single point of access. For example

  • Accessing application specific properties through a singleton object, which reads them for the first time from a properties file and subsequent accesses are returned from in-memory objects.
  • Creating a session factory. We need one session factory per database and use the same throughout our application. Singleton objects can be used for the same.

EXAMPLES in JDK

  • java.lang.Runtime class (getRuntime() method is used to return instance)
  • java.awt.Desktop class (getDesktop() method is used to return instance)

IMPLEMENTATION (advantages and disadvantages)

Singleton class can be implemented in following ways:

1. Early Initialization (static factory method): In this implementation, singleton gets instantiated at the time of class loading. The object is referenced by a static final field which gets returned each time singleton’s getInstance() method is called.

public class SingletonClass{
           private static final instance=new SingletonClass();
           public static SingletonClass getInstance(){
                                      return instance;
           }
 }

Advantages:

  • Instance cannot be redefined due to usage of final. (ensuring one and only one instance exists)
  • No use of expensive locking or synchronization as all threads see same instance. 

Disadvantages:

  • Since Singletons can be loaded only time per JVM in a class loader, the above implementation fails when the class gets loaded by multiple class loaders.

2. Lazy Initialization : In this implementation, the object of class gets constructed only when class is called.

public class SingletonClass{
          private static instance;
          public static SingletonClass getInstance(){
                    if(instance==null)
                           instance=new SingletonClass();
                                           return instance;
                 }
  }

Advantages:

  • Instance not constructed until class is used.

Disadvantages:

  • Since Singletons can be loaded only time per JVM in a class loader, the above implementation fails when the class gets loaded by multiple class loaders.
  • Unsynchronized i.e if two threads access the same method at same time, they both can create two different objects of the class.

3. Double checked locking : In this implementation, when two threads enter the getInstance() method at the same time, only one thread enters the synchronization block and constructs the instance. The other thread when allowed to enter the critical sections gets the instance and returns the same instance that the previous thread created, hence allowing only one instance per application.

public class SingletonClass{
     private static instance;
           public static SingletonClass getInstance(){
                   if(instance==null){
                synchronized(instance){
                      if(instance==null) 
                           instance=new SingletonClass();
                     }
                           }
         return instance;
          }
}

Advantages:

  • Instance not constructed until class is used.
  • Synchronized upto an extent

Disadvantages:

  • Since Singletons can be loaded only time per JVM in a class loader, the above implementation fails when the class gets loaded by multiple class loaders.
  • Static variables are initialized by JVM to default values if not explicitly initialized. Hence, threads can return the default values, when some thread is inside the critical section and busy constructing the singleton object.

4. Using volatile variable: Volatile variables are thread-safe, and changes by one thread are visible to others.Hence, in this implementation, the instance if changed, will be visible to all threads.

public class SingletonClass
{
      private static volatile SingletonClass instance;
      public static SingletonClass getInstance()
      {
            if( instance == null) 
                        instance = new SingletonClass();
            return instance;
      }
 }

Advantages:

  • OOP properities like inheritance can easily be applied.
  • Thread-safe

Disadvantages:

  • Since Singletons can be loaded only time per JVM in a class loader, the above implementation fails when the class gets loaded by multiple class loaders.

5. Using ENUMS: Singleton implementation using enums were introduced in JAVA 5. Enums are thread-safe and serializable. The properties are guaranteed by JVM itself. Hence, is the most efficient and easiest way to construct Singleton. One can easily access it by MySingleton.INSTANCE.

public enum MySingleton {
  INSTANCE;   
}

Since Singleton Pattern is about having a private constructor and calling some method to control the instantiations (like some getInstance), in Enums we already have an implicit private constructor. And the enum declaration actually compiles to something like

public final class MySingleton {
          public final static MySingleton INSTANCE = new MySingleton(); 
}

When the code first accesses INSTANCE, the class MySingleton will be loaded and initialized by the JVM. This process initializes the static field above once (lazily).

Advantages:

  • Reflection: It has the ability to access private members of any class. Hence, to avoid relection accessing our private constructor, we could either throw an Exception inside the constructor or use ENUM and let JVM handle it itself.
  • Serialiazation: readObject() of serialization always return a new instance of the class to be serialized. Although, we can override the readResolve() method of Serialization and return the same instance, still letting ENUM handle it becomes a better option.
  • Cloning: Multiple instances can be created through cloning. To prevent the another instance to be created of the singleton instance we can throw exception from inside the clone() method. Though enums cannot be cloned.

Disadvantage:

  • Cannot be extended as enums they final.

WHY NOT JUST MAKE THE OBJECT STATIC INSTEAD OF MAKING THE CLASS SINGLETON?

If we go through semantic point of view, to make user understand that only one instance per application exists, making the class Singleton would be the best option. Also, no new object will be created referring to same instance, that later needs to be garbage collected i.e if a class whose object is made static is heavy, then every time new MyClass() gets called, an object gets created occupying memory heap space unnecessary.

SINGLETONS v/s STATIC CLASS

This is a question asked when interviewer wants to know your deep knowledge about singletons. The question asked by him, would be like when static classes can also provide one instance and can be used without creating an object, why do we need Singletons?

When to use Singletons over Static classes:

  • Capable of providing different implementations, but guarantees only one instance per JVM. e.g getRuntime() method of java.lang.Runtime class returns different implementation on different JVM but guarantees one instance per JVM.
  • can be extended and implement interfaces.
  • Can be cloned, serialized, extended and lazily loaded.
  • Easier to test

 When to use Static classes over Singleton:

Classes that provides only static methods are called Static classes. e.g java.lang.Math

  • Faster than Singletons, as methods are bonded at compile time.
  • Due to inadequate synchronization, can lead to subtle race conditions when need to maintain state.
  • Always eagerly loaded.

SINGLETONS: ANTI PATTERN

Singletons are often badly implemented and hard to unit test. The memory allocated to them can’t be freed and excessive usage can lead us to Procedural programming (as with private constructor, there is no need to extend them!). Also, scope for which the instance is unique is hard to find. Because of these disadvantages of Singletons, they are considered to be anti-pattern.

Separate JREs are expected to use separate singleton instances as they can have multiple class-loaders. Global state increases coupling in our code and makes it hard to re-factor. Also, singleton implementation cannot be changed without changing it for all the classes accessing it.

Hence, singletons are avoided by many developers and instead Dependency Injection is recommended. (to be discussed in my next post)

A class which is used (almost) universally, but does not contain state relevant to your application, can safely be implemented as Singleton.

Hope you guys liked my post. Please feel free to ask any questions related to the topic in the comments below. 🙂