Monday, 20 July 2015

Difference between Dependency Injection and Factory Pattern in Java

TL;DR Main difference between dependency injection and factory pattern is that in case of former dependency is provided by third party (framework or container) while in case of later dependency is acquired by client class itself. Another key difference between them is that use of dependency injection result in loosely coupled design but use of factory pattern create tight coupling between factory and classes which are dependent on product created by factory. Though both Dependency Injection and Factory pattern looks similar in a sense that both creates instance of a class, and also promotes interface driven programming rather than hard coding implementation class; But, there are some subtle differences between Factory pattern and dependency injection pattern. In case of factory design pattern, client class is responsible for calling getInstance() of factory class to create instance of products, it also means that client class is directly coupled with factory and can't be unit tested without factory class being available. On the other hand in Dependency Injection, client class has no clue about how his dependencies are created and managed. It only knows about dependencies. Mostly dependencies are injected by framework e.g. bean class exists without any hard coded dependency, as those are injected by IOC container e.g. Spring. You can also used points used here to answer questions like difference between Spring IOC and Factory pattern because Spring IOC is nothing but an implementation of dependency injection pattern. BTW, if you are serious about learning design patterns and principles, I suggest you to take a look at Head First Object Oriented Analysis and design book. This book is overshadowed by its popular cousin Head First Design Pattern but its one of the book to master object oriented design principles and patterns.




Factory Pattern vs Dependency Injection

To understand difference between factory pattern and dependency injection better let's see examples of how both DI and Factory design pattern are used :

In Factory Pattern

public class CashRegister {

    private PriceCalculator calculator = PriceCalculatorFactory.getInstance();

    public void add(Transaction tx) {
          int price = calcualtor.getPrice(tx);
          add(price);
    }

}

In this case dependent class, CashRegister is directly coupled with PriceCalculatorFactory because its calling static getInstance() method from PriceCalculatorFactory to satisfy its dependency. In order to test CashRegister, you must need a PriceCalculatorFactory, which is not good for unit testing of this class. On the other hand, if you use Dependency injection, then dependencies are added by framework e.g. Spring framework or DI container like Google Guice because you reverse the responsibility of acquiring dependencies. Now it's responsibility of IOC container to inject dependency than the dependent class fending for himself. In case of dependency injection any class just looks like a POJO.

In Dependency Injection 

public class CashRegister {

    private PriceCalculator calculator;

    public CashRegister(PriceCalculator calculator){
        this.calculator = calculator;
    }

    public void add(Transaction tx) {
          int price = calcualtor.getPrice(tx);
          add(price);
    }

    public void setCalcuator(PriceCalculator calc){
        this.calculator = calc;
    }

}

You can see that dependency for CashRegister, which is PriceCalculator is supplied via constructor, this is known as constructor dependency injection. There is other form of DI as well e.g. setter injection, in which dependency is provided using setter method. For example, setCalcuator(PriceCalcuator) is facilitating setter injection there. You should use constructor injection to inject mandatory dependencies and setter injection for optional, good to have dependencies. You can also see when to use Setter vs Constructor injection for more guidelines.


Difference between Factory Pattern vs Dependency Injection

Based upon our knowledge of both of these patterns, you can easily deduce following key differences between them :

1) Factory pattern adds coupling between object, factory and dependency. Object not only needs dependent object to work properly but also a Factory object. While in case of dependency injection, Object just know the dependency, it doesn't know anything about container or factory


2) As compared to Factory pattern, Dependency injection makes unit testing easier. If you use factory pattern, you need to create the object you want to test, the factory and the dependent object, ofcourse you factor can return mock object, but you need all this just to start with unit testing. On the other hand, if you use dependency injection, you just need to mock the dependency and inject into object you want to test, no clutter or boiler plate is needed.


3) Dependency injection is more flexible than factory pattern. You can even switch to different DI framework e.g. Spring IOC or Google Guice.


4) One of the drawback of Dependency injection as compared to Factory pattern is that you need a container and configuration to inject dependency, which is not required if you use factory design pattern. In true sense, its not such a bad thing because you have one place to see dependency of your class and you can control them, but yes when you compare DI to factory method, this is the additional step you need to do.


5) Due to low coupling, DI results in much cleaner co than factory pattern. Your object looks like POJO and you also come to know what is mandatory and what is option by looking which type of dependency injection your class is using. If an object is injected using Setter injection, which means its optional and can be injected in any time, while dependencies which are injected using constructor injection means they are mandatory and must be supplied in the order they are declared.


6) Another tricky scenario with using DI is creating an object with too many dependency and worse if those are injected using constructor injection. Those co becomes difficult to read. One solution of those problem is to use Facade pattern and inject dependencies by encapsulating in another object. For example, you can introduce an object say ApplicationSettings which can contain DBSetting, FileSetting and other configuration settings required by object.


7) You should use Dependency Injection Patterns to introduce loose coupling. Use Factory Patterns if you need to delegate the creation of objects. In short, dependency injection frees your application from factory pattern boiler plate code. All the work which is required to implement a factory is already done by IOC containers like Spring and Google Guice.


That's all between difference between Factory design pattern and dependency injection in Java. Both patterns, takes out the creation of dependencies from dependent class, and encourages use of interfaces for defining property e.g. here we are using PriceCalculator which is an interface, so that it can later be replaced by any suitable implementation without affecting any part of code. Difference between factory and dependency injection lies on the fact that in case of factory, your dependent class is still dependent on factory, which is a new form of dependency, while DI takes out the dependency completely. Which means dependency injection provides better decoupling and unit testing of classes over Factory design pattern.

Difference between Factory pattern and dependency injection
If you like this article and interested to learn more about design patterns and principles, you may like following ones as well :
  • What is difference between Adapter, Decorator and Proxy design patterns? (answer)
  • How to implement Builder design Pattern in Java? (solution)
  • 10 Object Oriented Design Principle Every Programmer Should know (principles)
  • What is Open Closed design Principle in OOP? (answer)
  • What is difference between Factory and Abstract Factory design Patterns? (answer)
  • 5 Reasons to use Composition in place of Inheritance in Java? (answer)
  • How to implement Strategy Design Pattern using Java Enum? (solution)
  • What is difference between State and Strategy Pattern in Java? (answer)
  • Top 5 Books to Learn Design Patterns and Principles (books)
  • How to implement DAO design Pattern in Java? (answer)
  • Why implementing Singleton using Enum is better than Class in Java? (answer)
  • What is difference between Association, Aggregation and Composition in OOP? (answer)
  • Difference between Singleton and Static Class in Java? (answer)
  • Why you should Interface for Coding in Java? (answer)
  • Real life example of Decorator Pattern in Java? (example)

Recommended books for further reading on design patterns for Java developers 

  • Head First Design Pattern by Kathy Sierra (check here)
  • Refactoring, Improving design of existing code (check here)
  • Head First Object-Oriented Analysis and design (check here)

2 Ways to check If String is Palindrome in Java? Recursion and Loop

A String is said to be Palindrome if it is equal to itself in reverse order. You can use this logic to check if String is Palindrome or not. There are two common ways to find if a given String is Palindrome or not in Java, first by using for loop, also known as iterative algorithm and second by using recursion, also known as recursive algorithm. The crux of this problem lies in how do you reverse String in Java? because once you have the String in reverse order, problem reduced to just comparing itself with the reversed String. If both are equal then given String is Palindrome otherwise it's not. Also whether your solution is iterative or recursive will also determine by implementing this logic. If you reverse String using for loop then it become an iterative solution and if you reverse String using recursion then it become a recursive solution. In general, recursive solution are short, readable and more intuitive but subject to StackOverFlowError and that's why not advised to be used in production system. You should always be using iterative solution in production, unless your programming language supports tail recursion optimization e.g. Scala which eliminates risk of StackOverFlowError by internally converting a recursive solution to an iterative one. If you are doing this exercise as part of your Interview preparation then I suggest you to take a look at Cracking the Coding Interview: 150 Programming Questions and Solutions, as title says it contains 150 good questions based upon different topics e.g. String, array, linked list, binary tree, networking etc. A good book for preparing both Java and C++ interview.




Solution 1 : How to check if String is Palindrome using Recursion

Easiest way to find if a given String is Palindrome or not is by writing a recursive function to reverse the String first and then comparing given String with the reversed String, if both are equal then given String is palindrome. This logic is coded in our static utility method isPalindrome(String input) method. This method calls another method called reverse(String str), which is responsible for reversing given String using recursion. This method take out the last character and passed the rest of the String to the reverse() method itself,  when a method calls itself is called recursion. A recursive function needs a based case to terminate recursion and produce result. In this program, base case is empty String, if String is empty just return itself and don't call the method. We are also using substring() method from java.lang.String class to reduce the String in every call so that our solution reaches to base case after every call. If you remember the structure is quite similar to our earlier solution of problem how to find if a number is Palindrome in Java. Only thing different there was the logic to reverse numbers.



Solution 2 : How to check if String is Palindrome using Iteration

In our second solution we will try to solve this problem by using for loop. If you use any loop e.g. for, while or do..while then your solution is known as iterative solution. This solution uses extra space in form of StringBuilder which may or may not be allowed sometime. You can check with your interviewer whether you can use StringBuffer to reverse String in Java or not. He may not allow directly using reverse() method but he may allow it for String concatenation. The logic of this solution is coded in method checkPalindrome(String text). This method first create reversed String by iterating over String in reverse order e.g. starting from last index and going towards first index. You can easily do this in a for loop because it allows you to control index. It's actually quite similar to how you loop over array because String is a character array and you can get character array from String by calling toCharArray() method. Once you reverse the given String, its all about check if two Strings are equal to each other using equals() method, if it returns true then String is Palindrome.



Java Program to check if String is Palindrome Or Not

Here is our complete Java solution to problem of check if given String is Palindrome or not. This example program contains two methods, isPalindrome() and checkPalindrom(), first method check if String is Palindrome using loop while second method checks if String is Palindrome using recursion. We also have JUnit tests written to unit test our solution. I have two test methods testPalindromeRecursive() and testPalindrome(), first one tests our recursive solution and second one tests our iterative algorithm. You can see input there, "madam" is a Palindrome and our solution should return true for it. The line assertTrue(isPalindrome("madam")); does exactly same thing, it checks whether isPalindrome() method returns true for "madam" or not. 


import static org.junit.Assert.*;

import org.junit.Test;

/**
 * Java program to check if given String is palindrome or not.
 *
 * @author WINDOWS 8
 */

public class PalindromeChecker {

    /*
     * This method check if a given String is palindrome or not using recursion
     */
    public static boolean isPalindrome(String input) {
        if (input == null) {
            return false;
        }
        String reversed = reverse(input);

        return input.equals(reversed);
    }

    public static String reverse(String str) {
        if (str == null) {
            return null;
        }

        if (str.length() <= 1) {
            return str;
        }

        return reverse(str.substring(1)) + str.charAt(0);
    }
   
    /*
     * Iterative algorithm to check if given String is palindrome or not
     */
    public static boolean checkPalindrome(String text){
       
        StringBuilder sb = new StringBuilder(text);
        char[] contents = text.toCharArray();
       
        for(int i = text.length() -1; i>=0 ; i--){
            sb.append(contents[i]);
        }
       
        String reversed = sb.toString();
       
        return text.equals(reversed);
    }
   
    @Test
    public void testPalindromeRecursive(){
        assertTrue(isPalindrome("madam"));
        assertFalse(isPalindrome("programming"));
        assertTrue(isPalindrome(""));
        assertTrue(isPalindrome("AIA"));
    }
   
    @Test
    public void testPalindrome(){
        assertFalse(isPalindrome("wonder"));
        assertFalse(isPalindrome("cat"));
        assertTrue(isPalindrome("aaa"));
        assertTrue(isPalindrome("BOB"));
    }
}

Output
All test passes

How to check if String is Palindrome in Java


That's all about how to check if String is Palindrome in Java. You have learned both iterative and recursive algorithms to verify whether String is Palindrome or not. If you are asked to write code about this problem, you first write code to check if String is palindrome using for loop, this will prompt Interviewer to ask you again to write same code using recursion and that time you write your solution using recursion. This will help you to drive the interview according to your plan and you will score more brownie points, just make sure that you don't rush for solution but spend some time thinking about it.

If you like this coding interview question and looking for some more coding problems for practice, you can check out some of programming questions from this blog :
  • How to check if two String are Anagram or not? [solution]
  • How to check if array contains a number in Java? [solution]
  • Write a program to find missing number in integer array of 1 to 100? [solution]
  • How do you reverse array in place in Java? [solution]
  • How to check duplicate elements from Array in Java? [solution]
  • How to remove duplicates from array in Java? [solution]
  • Write a program to find top two numbers from an integer array? [solution]
  • How to find maximum and minimum number in unsorted array? [solution]
  • How to find all pairs on integer array whose sum is equal to given number? [solution]
  • How to sort an array in place using QuickSort algorithm? [solution]
  • How do you remove duplicates from array in place? [solution]

Recommended books to Prepare for Coding Interviews

If you are preparing for programming job interviews to find a software developer position then you must prepare for coding problems. Following books will help you to better prepare for your software engineering interview :
  • Coding Puzzles: Thinking in code By codingtmd (check here)
  • Programming Interviews Exposed: Secrets to Landing Your Next Job (check here)
  • Cracking the Coding Interview: 150 Programming Questions and Solutions (check here)