April 26, 2016

Java Design Pattern Interview Questions & Answers

What are Design Patterns?
Design patterns are tried and tested way to solve particular design issues by various programmers in the world. Design patterns are extension of code reuse.

Design patterns versus frameworks
Are design patterns the same thing as frameworks? The answer to that is NO. Design patterns are more like general guidelines on how to solve specific programming problems, but they do not specify the detailed code that’s necessary to solve those problems.

Name types of Design Patterns?
  • Creational Patterns - These design patterns provide a way to create objects while hiding the creation logic, rather than instantiating objects directly using new opreator. This gives program more flexibility in deciding which objects need to be created for a given use case. e.g Singleton, Factory pattern.
  • Structural Patterns - These design patterns concern class and object composition. (Composition is a 'has-a' relationship e.g Room 'has-a' Chair.) Concept of inheritance is used to compose interfaces and define ways to compose objects to obtain new functionalities. Structural design patterns are concerned with how classes and objects can be composed, to form larger structures.e.g Private Class Data, Decorator etc.
  • Behavioral Patterns - These design patterns are specifically concerned with communication between objects. e.g Template Method, Visitor, Iterator, Observer etc.
What is Singleton pattern?
Singleton pattern is one of the simplest design patterns in Java. This type of design pattern comes under creational pattern as this pattern provides one of the best ways to create an object.

This pattern involves a single class which is responsible to create an object while making sure that only single object gets created. This class provides a way to access its only object which can be accessed directly without need to instantiate the object of the class.

There are many classes in JDK which is implemented using Singleton pattern like : Java.lang.Runtime with getRuntime() method, Java.awt.Toolkit with getDefaultToolkit() and Java.awt.Desktop with getDesktop() etc.

How can you create Singleton class in java?
It is two step process. First, make the constructor private so that new operator cannot be used to instantiate the class. Return an object of the object if not null otherwise create the object and return the same via a method.

What are the difference between a static class and a singleton class?
a. A static class can not implement interfaces where a singleton class can.
b. All members of a static class are static but for a Singleton class it is not a requirement.
c. A static class get initialized when it is loaded so it can not be lazily loaded where a singleton class can be lazily loaded.
d. A static class object is stored in stack whereas singlton class object is stored in heap memory space.
e. We can clone the object of Singleton but, we can not clone the static class object.

Can we create a clone of a singleton object?
Yes.

How to prevent cloning of a singleton object?
Throw exception within the body of clone() method.

What is double checked locking in Singleton?
Double checked locking is a technique to prevent creating another instance of Singleton when call to getInstance() method is made in multi-threading environment.
public static Singleton getInstance(){
     if(_INSTANCE == null){
         synchronized(Singleton.class){
         //double checked locking - because second check of Singleton instance with lock
                if(_INSTANCE == null){
                    _INSTANCE = new Singleton();
                }
            }
         }
     return _INSTANCE;
}

Explain in singleton pattern whether it is better to make the whole getinstance() method synchronized or just critical section is enough? Which one is preferable?
Synchronization of whole getinstance() method is costly and is only needed during the initialization on singleton instance, to stop creating another instance of Singleton.  Therefore it is better to only synchronize critical section and not the whole method.

What is lazy and early loading of Singleton and how will you implement it?
As there are many ways to implement Singleton like using double checked locking or Singleton class with static final instance initialized during class loading. Former is called lazy loading because Singleton instance is created only when client calls getInstance() method while later is called early loading because Singleton instance is created when class is loaded into memory.

How do you prevent for creating another instance of Singleton during serialization?
You can prevent this by using readResolve() method, since during serialization readObject() is used to create instance and it return new instance every time but by using readResolve you can replace it with original Singleton instance.

ALSO READ: Serialization of Singleton class..

How many ways you can write Singleton Class in Java?
a. Singleton by synchronizing getInstance() method
b. Singleton with public static final field initialized during class loading.
c. Singleton generated by static nested class, also referred as Singleton holder pattern.
d. From Java 5 on-wards using Enums

How to create singleton class in Java using ENUM?
Though Singleton pattern in Java exists from long time Enum Singletons are relatively new concept and in practice from Java 5 onward after introduction of Enum as keyword and feature.

public enum MySingleton{
  INSTANCE; 
  public void doIt(){
    System.out.println("Singleton using Enum");
  }

}

By this way you ca create a singleton class using enum, if you want you can declare instance variable and instance method inside it. If you are using any instance method than you need to ensure thread-safety of that method if at all it affect the state of object. By default creation of Enum instance is thread safe but any other method on Enum is developers responsibility.

Whenever you want instance of singleton class, call MySingleton.INSTANCE. It is much easier than calling getInstance() method on Singleton.

Why Enum Singleton are better in Java?

1). Enum Singleton are easy to write and Enum instance is thread-safe.

#Suppose you want to implement singleton class with double checked locking, then you need to write getInstance() method as:

public MySingletonDoubleCheckedLocking getInstance(){
    if(INSTANCE == null){
        synchronized(MySingletonDoubleCheckedLocking.class){
                if(INSTANCE == null){
                    INSTANCE = new MySingletonDoubleCheckedLocking();
                }
            }
         }
     return INSTANCE;
}


#There is one more way to create a singleton class in Java, by using static factory method.In this Singleton instance is static and final variable, it is initialized when class is first loaded into memory so creation of instance is inherently thread-safe. You can call MyStaticSingleton.getSingleton() to get access of this class.

public class MyStaticSingleton{
    //initailzed during class loading
    private static final MyStaticSingleton INSTANCE = new MyStaticSingleton();

    //to prevent creating another instance of MyStaticSingleton
    private MyStaticSingleton(){}

    public static MyStaticSingleton getSingleton(){
        return INSTANCE;
    }
}


In both the above ways we need to write so many line of codes in getInstance(), but with Enum Singleton pattern we can have that in just one line because creation of Enum instance is thread-safe and guaranteed by JVM.

2). Enum Singletons handled Serialization by themselves.
If you are using conventional way to create a singleton class and implement serializable interface, then you need to take extra care because readObject() method always return a new instance just like constructor in Java. You need to add readResolve() method in the singleton class, which discards the newly created instance by replacing with Singleton. e.g:

private Object readResolve(){
    return INSTANCE;
}


This can become even more complex if your Singleton Class maintain state, as you need to make them transient, but with Enum Singleton, Serialization is guaranteed by JVM.

What are the problems with enum as singleton?
  • enums do not support lazy loading.
  • Though it’s very very rare but if you changed your mind and now want to convert your singleton to multi-ton, enum would not allow this.

Give an example scenario where you will use singleton pattern.
Assume what we are writing an application that needs to log events in a log file. Logging is done with timestamp. We do not want to have more than one instances of Logger otherwise the log file will be created with every instance. In this case, we use Singleton pattern and instantiate the logger when the first request comes or when the server is started.

Mention what is the limitation of using singleton pattern?
The singleton pattern ensures that a class has only one instance and to provide a global point of access to it. But at the same time this becomes its limitation as most classes in an application you will need to create multiple instances.

Why can’t we use a static class instead of singleton?
  • Singleton class can implement interfaces and extend classes while the static class cannot (it can extend classes, but it does not inherit their instance members). If we consider a static class it can only be a nested static class as top level class cannot be a static class. Static means that it belongs to a class it is in and not to any instance. So it cannot be a top level class.
  • Static class will have all its member as static only unlike Singleton.
  • It can be lazily loaded whereas static will be initialized whenever it is first loaded.
  • Singleton object stores in Heap but, static object stores in stack.
  • We can clone the object of Singleton but, we can not clone the static class object.
Which is better in Java, implementing public static methods or a singleton class?
It depends on what you want. Whenever you want the object state (e.g. Polymorphism like Null state instead of null, or default state), singleton is the appropriate choice for you whereas the static method use when you need function (Receive inputs then return an output).

Advantage of singleton is that when in future you decide that this object should no longer be a singleton (due to new insights or new requirements), it is easier to refactor it( we just need to change all the places that get the instance, instead of all calls to the static methods).

Name some of the design patterns which are used in JDK library.
# Decorator pattern is used by Wrapper classes.
# Singleton pattern is used by Runtime, Calendar classes.
# Factory pattern is used by Wrapper class like Integer.valueOf.
# Observer pattern is used by event handling frameworks like swing, awt.

What is Factory method Design Pattern?
It is one of most used design pattern in Java. This type of design pattern comes under creational pattern as this pattern provides one of the best ways to create an object. In Factory pattern, we create object without exposing the creation logic to the client and refer to newly created object using a common interface.

The factory pattern is preferred in the following cases: A class does not know which class of objects it must create or a factory pattern can be used where we need to create an object of any one of sub-classes depending on the data provided.


Factory pattern can be used:
  • When a class does not know which class of objects needs to create
  • When class specifies its sub-classes to specify which objects to create
  • In programming language, you can use factory pattern where you have to create an object of any one of sub-classes depending on the given data.
What is the benefit of Factory pattern?
Factory pattern encapsulates the implementation details and underlying implementation can be changed without any impact on caller api.

Example of Factory Design Pattern:

Step 1).
public interface Shape {
   void draw();
}


Step 2).
public class Rectangle implements Shape {
   @Override
   public void draw() {
      System.out.println("**Inside Rectangle draw() method.");
   }
}

public class Square implements Shape {
   @Override
   public void draw() {
      System.out.println("**Inside Square draw() method.");
   }
}

public class Circle implements Shape {
   @Override
   public void draw() {
      System.out.println("**Inside Circle draw() method.");
   }
}


Step 3).
public class ShapeFactory {   
    public Shape getShape(String shapeType){
      if(shapeType == null){
         return null;
      }       
      else if(shapeType.equalsIgnoreCase("CIRCLE")){
         return new Circle();
        
      } else if(shapeType.equalsIgnoreCase("RECTANGLE")){
         return new Rectangle();
        
      } else if(shapeType.equalsIgnoreCase("SQUARE")){
         return new Square();
      } else
      {
         return null;
      }
   }
}


Step 4).
public class FactoryPatternDemo {
   public static void main(String[] args) {
      ShapeFactory shapeFactory = new ShapeFactory();
      Shape shape1 = shapeFactory.getShape("CIRCLE");
      shape1.draw();

      Shape shape2 = shapeFactory.getShape("RECTANGLE");
      shape2.draw();
     
      Shape shape3 = shapeFactory.getShape("SQUARE");
      shape3.draw();
   }
}


Output of FactoryPatternDemo is:
**Inside Circle draw() method.
**Inside Circle draw() method.
**Inside Circle draw() method.


What is Abstract Factory pattern?
Abstract Factory patterns work around a super-factory which creates other factories. This factory is also called as factory of factories. This type of design pattern comes under creational pattern as this pattern provides one of the best ways to create an object. In Abstract Factory pattern an interface is responsible for creating a factory of related objects without explicitly specifying their classes. Each generated factory can give the objects as per the Factory pattern.

Abstract factory pattern provides abstraction one level higher than factory pattern. It encapsulates a group of individual factories.
Step 1).
public interface Shape {
   void draw();
}

Step 2).
public class Rectangle implements Shape {
   @Override
   public void draw() {
      System.out.println("**Inside Rectangle draw() method.");
   }
}

public class Square implements Shape {
   @Override
   public void draw() {
      System.out.println("**Inside Square draw() method.");
   }
}

public class Circle implements Shape {
   @Override
   public void draw() {
      System.out.println("**Inside Circle draw() method.");
   }
}

Step 3).
public interface Color {
   void fill();
}

Step 4).
public class Red implements Color {
   @Override
   public void fill() {
      System.out.println("**Inside Red fill() method.");
   }
}

public class Green implements Color {
   @Override
   public void fill() {
      System.out.println("**Inside Green fill() method.");
   }
}

public class Blue implements Color {
   @Override
   public void fill() {
      System.out.println("**Inside Blue fill() method.");
   }
}

Step 5).
public abstract class AbstractFactory {
   abstract Color getColor(String color);
   abstract Shape getShape(String shape) ;
}

Step 6).
public class ShapeFactory extends AbstractFactory{   
    public Shape getShape(String shapeType){
      if(shapeType == null){
         return null;
      }       
      else if(shapeType.equalsIgnoreCase("CIRCLE")){
         return new Circle();
        
      } else if(shapeType.equalsIgnoreCase("RECTANGLE")){
         return new Rectangle();
        
      } else if(shapeType.equalsIgnoreCase("SQUARE")){
         return new Square();
      } else
      {
         return null;
      }
   }
}

@Override
   Color getColor(String color) {
      return null;
}

public class ColorFactory extends AbstractFactory {   
   @Override
   public Shape getShape(String shapeType){
      return null;
   }
  
   @Override
   Color getColor(String color) {  
      if(color == null){
         return null;
      }         
      else if(color.equalsIgnoreCase("RED")){
         return new Red();        
      }else if(color.equalsIgnoreCase("GREEN")){
         return new Green();        
      }else if(color.equalsIgnoreCase("BLUE")){
         return new Blue();
      } else
      {     
        return null;
      }
   }
}

Step 7).
public class FactoryProducer {
   public static AbstractFactory getFactory(String choice){
  
      if(choice.equalsIgnoreCase("SHAPE")){
         return new ShapeFactory();
        
      }else if(choice.equalsIgnoreCase("COLOR")){
         return new ColorFactory();
      }
     
      return null;
   }
}

Step 8).
public class AbstractFactoryPatternDemo {
   public static void main(String[] args) {
      AbstractFactory shapeFactory = FactoryProducer.getFactory("SHAPE");
      Shape shape1 = shapeFactory.getShape("CIRCLE");
      shape1.draw();

      Shape shape2 = shapeFactory.getShape("RECTANGLE");
      shape2.draw();
      Shape shape3 = shapeFactory.getShape("SQUARE");
      shape3.draw();

      AbstractFactory colorFactory = FactoryProducer.getFactory("COLOR");
      Color color1 = colorFactory.getColor("RED");
      color1.fill();
      Color color2 = colorFactory.getColor("Green");
      color2.fill();
      Color color3 = colorFactory.getColor("BLUE");
      color3.fill();
   }
}

Output of the AbstractFactoryPatternDemo :
**Inside Circle draw() method.
**Inside Rectangle draw() method.
**Inside Square draw() method.
**Inside Red fill() method.
**Inside Green fill() method.
**Inside Blue fill() method.


What is the difference between factory design pattern and abstract factory design pattern?
Both are creational design patterns. Factory pattern is said to be there if there is method in a class that is used to create class instances. Any class can have factory methods. Using abstract factory pattern, an instance of a class is created that has only factory methods.

What is MVC pattern?
MVC Pattern stands for Model-View-Controller Pattern. This pattern is used to separate application's concerns.
  • The model represents the state (data) and business logic of the application.
  • The view module is responsible to display data i.e. it represents the presentation.
  • The controller module acts as an interface between view and model. It intercepts all the requests i.e. receives input and commands to Model / View to change accordingly.

What is Decorator pattern?
Decorator pattern allows a user to add new functionality to an existing object without altering its structure. This type of design pattern comes under structural pattern as this pattern acts as a wrapper to existing class. This pattern creates a decorator class which wraps the original class and provides additional functionality keeping class methods signature intact.

It is used to modify the functionality of an object at runtime. At the same time other instances of the same class will not be affected by this, so individual object gets the modified behavior.  e.g Adapter Pattern, Bridge Pattern, Composite Pattern.

Decorator Design Pattern in Java API
  • java.io.BufferedReader;
  • java.io.BufferedWriter;
  • java.io.FileReader;
  • java.io.Reader; 

e.g BufferedReader decorates InputStreamReader.

BufferedReader input = new BufferedReader(new InputStreamReader(System.in));
//where 'System.in' is an InputStream object

  • InputStreamReader(InputStream in): Bridge from byte streams to character streams. InputSteamReader reads bytes and translates them into characters using the specified character encoding.
  • BufferedReader(Reader in): read text from a character stream and buffer characters in order to provide efficient reading methods(e.g., readLine())
Step 1).
public interface Shape {
   void draw();
}

Step 2).
public class Rectangle implements Shape {
   @Override
   public void draw() {
      System.out.println("Shape is Rectangle");
   }
}

public class Circle implements Shape {
   @Override
   public void draw() {
      System.out.println("Shape is Circle");
   }
}

Step 3).
public abstract class ShapeDecorator implements Shape {
   protected Shape decoratedShape;
   public ShapeDecorator(Shape decoratedShape){
      this.decoratedShape = decoratedShape;
   }
   public void draw(){
      decoratedShape.draw();
   }   
}

Step 4).
public class RedShapeDecorator extends ShapeDecorator {
   public RedShapeDecorator(Shape decoratedShape) {
      super(decoratedShape);       
   }

   @Override
   public void draw() {
      decoratedShape.draw();          
      setRedBorder(decoratedShape);
   }
   private void setRedBorder(Shape decoratedShape){
      System.out.println("Border Color is set as Red");
   }
}

Step 5).
public class DecoratorPatternDemo {
   public static void main(String[] args) {
      Shape circle = new Circle();
      Shape redCircle = new RedShapeDecorator(new Circle());
      Shape redRectangle = new RedShapeDecorator(new Rectangle());
      circle.draw();
      redCircle.draw();
      redRectangle.draw();
   }
}

Output of DecoratorPatternDemo:
Shape is Circle
Shape is Circle
Border Color is set as Red
Shape is Rectangle
Border Color is set as Red


What is Bridge pattern?
Bridge pattern comes under structural pattern as it decouples implementation class and abstract class by providing a bridge structure between them. It is used when we need to decouple an abstraction from its implementation so that the two can vary independently.

This pattern involves an interface which acts as a bridge which makes the functionality of concrete classes independent from interface implementer classes. Both types of classes can be altered structurally without affecting each other.
 Step 1).
public interface DrawAPI {
   public void drawCircle(int radius, int x, int y);
}

Step 2).
public class RedCircle implements DrawAPI {
   @Override
   public void drawCircle(int radius, int x, int y) {
      System.out.println("Drawing Circle in red color with radius= " + radius + ", x= " + x + ", y=" + y );
   }
}

public class GreenCircle implements DrawAPI {
   @Override
   public void drawCircle(int radius, int x, int y) {
      System.out.println("Drawing Circle in green color with radius= " + radius + ", x= " + x + ", y=" + y );
   }
}

Step 3).
public abstract class Shape {
   protected DrawAPI drawAPI;
 
   protected Shape(DrawAPI drawAPI){
      this.drawAPI = drawAPI;
   }
   public abstract void draw();  
}

Step 4).
public class Circle extends Shape {
   private int x, y, radius;

   public Circle(int x, int y, int radius, DrawAPI drawAPI) {
      super(drawAPI);
      this.x = x;
      this.y = y;
      this.radius = radius;
   }

   public void draw() {
      drawAPI.drawCircle(radius,x,y);
   }
}

Step 5).
public class BridgePatternDemo {
   public static void main(String[] args) {
      Shape redCircle = new Circle(100,100, 10, new RedCircle());
      Shape greenCircle = new Circle(100,100, 10, new GreenCircle());

      redCircle.draw();
      greenCircle.draw();
   }
}

What is Adapter pattern?
Adapter pattern comes under structural pattern as this pattern combines the capability of two independent interfaces. It works as a bridge between two incompatible interfaces. This pattern involves a single class which is responsible to join functionalities of independent or incompatible interfaces. For example a card reader which acts as an adapter between memory card and a laptop. You plugin the memory card into card reader and card reader into the laptop so that memory card can be read via laptop.

What is Template pattern?
Template pattern comes under behavior pattern category. In this pattern, an abstract class exposes defined way(s) or template(s) to execute its methods. The subclasses can override the method implementation as per need, but the invocation is to be in the same way as defined by an abstract class.

The AbstractClass contains the templateMethod(), which should be made final so that it cannot be overridden. This template method makes use of other operations available in order to run the algorithm, but is decoupled for the actual implementation of these methods. All operations used by this template method are made abstract, so their implementation is deferred to subclasses.

The ConcreteClass implements all the operations required by the templateMethod that were defined as abstract in the parent class. There can be many different ConcreteClasses. 

Let’s understand this pattern with an example, suppose we want to provide an algorithm to build a house. The steps need to be performed to build a house are – building foundation, building pillars, building walls and windows. The important point is that the we can’t change the order of execution because we can’t build windows before building the foundation. So in this case we can create a template method that will use different methods to build the house.

Now building the foundation for a house is same for all type of houses, whether its a wooden house or a glass house. So we can provide base implementation for this, if subclasses want to override this method, they can but mostly it’s common for all the types of houses.

What is Observer design pattern in Java? When do you use Observer pattern in Java?
It falls under behavioral pattern category, as name suggest it’s used to observe things. Observer pattern is used when there is one-to-many relationship between objects such as if one object is modified, its dependent objects are to be notified automatically.

Object which is being observed is refereed as Subject and classes which observe subject are called Observer.

Step 1).
public abstract class Observer {
   protected Subject subject;
   public abstract void update();
}

Step 2).
import java.util.ArrayList;
import java.util.List;
public class Subject {   
   private List observers = new ArrayList();
   private int state;

   public int getState() {
      return state;
   }

   public void setState(int state) {
      this.state = state;
      notifyAllObservers();
   }

   public void attach(Observer observer){
      observers.add(observer);       
   }

   public void notifyAllObservers(){
      for (Observer observer : observers) {
         observer.update();
      }
   }    
}

Step 3). Create concrete observer classes
public class BinaryObserver extends Observer{

   public BinaryObserver(Subject subject){
      this.subject = subject;
      this.subject.attach(this);
   }

   @Override
   public void update() {
      System.out.println( "Binary String= " + Integer.toBinaryString(subject.getState() ) );
   }
}

public class HexaObserver extends Observer{

   public HexaObserver(Subject subject){
      this.subject = subject;
      this.subject.attach(this);
   }

   @Override
   public void update() {
      System.out.println( "Hex String= " + Integer.toHexString( subject.getState() ).toUpperCase() );
   }
}

public class OctalObserver extends Observer{

   public OctalObserver(Subject subject){
      this.subject = subject;
      this.subject.attach(this);
   }

   @Override
   public void update() {
     System.out.println( "Octal String= " + Integer.toOctalString( subject.getState() ) );
   }
}

Step 4).
public class ObserverPatternDemo {
   public static void main(String[] args) {
      Subject subject = new Subject();

      new HexaObserver(subject);
      new OctalObserver(subject);
      new BinaryObserver(subject);

      System.out.println("First state change= 15");   
      subject.setState(15);
      System.out.println("Second state change= 10");   
      subject.setState(10);
   }
}

Output of ObserverPatternDemo:
First state change= 15
Hex String= F
Octal String= 17
Binary String= 1111
Second state change= 10
Hex String= A
Octal String= 12
Binary String= 1010


Builder Design Pattern comes under creational pattern, it builds a complex object using simple objects and using a step by step approach. A Builder class builds the final object step by step. This builder is independent of other objects.

Constructors in Java are used to create object and can take parameters required to create object. Problem starts when we create a complex Object from constructor with lot of parameters, some of them may be mandatory and others may be optional.

Consider a class which is used to create Pizza, now you need number of item like crust, cheeze, sauces, toppings to create Pizza. Many of them are mandatory and some of them are optional like green olives or spinach alfredo sauce etc. If we are going to have overloaded constructor for different kind of Pizza then there will be many constructor and even worst they will accept many parameter.

So the problem is that:
1. There will be too many constructors to maintain.
2. It will error prone because many fields has same type e.g. two types of sauce in different quantity (you might put wrong quantity of sauce abd compiler will not complain since the 'type' is same).

You can partially solve this problem by creating Pizza and then adding ingredients later, but that will impose another problem of leaving Object on inconsistent state during building, ideally Pizza should not be available until its created.

These problems can be solved by using Builder design pattern in Java. Builder design pattern not only improves readability but also reduces chance of error by adding ingredients explicitly and making object available once fully constructed.

public class Pizza {
    private final int spinachAlfredoSauce, ranchSauce;
    private final double cheese, pizzacrust;
    private final double bananaPeppersToppings, ripeOlivesToppings, greenOlivesToppings;
   
    public Pizza(Builder builder) {
        this.spinachAlfredoSauce = builder.spinachAlfredoSauce;
        this.ranchSauce = builder.ranchSauce;
        this.cheese = builder.cheese;
        this.pizzacrust = builder.pizzacrust;
        this.bananaPeppersToppings = builder.bananaPeppersToppings;
        this.ripeOlivesToppings = builder.ripeOlivesToppings;
        this.greenOlivesToppings = builder.greenOlivesToppings;
    }

    @Override
    public String toString() {
        return "Pizza [spinachAlfredoSauce=" + spinachAlfredoSauce
                + ", ranchSauce=" + ranchSauce + ", cheese=" + cheese
                + ", pizzacrust=" + pizzacrust + ", bananaPeppersToppings="
                + bananaPeppersToppings + ", ripeOlivesToppings="
                + ripeOlivesToppings + ", greenOlivesToppings="
                + greenOlivesToppings + "]";
    }

    public static class Builder
    {
        private int spinachAlfredoSauce, ranchSauce;
        private double cheese, pizzacrust;
        private double bananaPeppersToppings, ripeOlivesToppings, greenOlivesToppings;
       
        public Builder spinachAlfredoSauce(int spinachAlfredoSauce) {
            this.spinachAlfredoSauce = spinachAlfredoSauce;
            return this;
        }
        public Builder ranchSauce(int ranchSauce) {
            this.ranchSauce = ranchSauce;
            return this;
        }
        public Builder cheese(double cheese) {
            this.cheese = cheese;
            return this;
        }
        public Builder pizzacrust(double pizzacrust) {
            this.pizzacrust = pizzacrust;
            return this;
        }
        public Builder bananaPeppersToppings(double bananaPeppersToppings) {
            this.bananaPeppersToppings = bananaPeppersToppings;
            return this;
        }
        public Builder ripeOlivesToppings(double ripeOlivesToppings) {
            this.ripeOlivesToppings = ripeOlivesToppings;
            return this;
        }
        public Builder greenOlivesToppings(double greenOlivesToppings) {
            this.greenOlivesToppings = greenOlivesToppings;
            return this;
        }
       
        public Pizza build() {
            return new Pizza(this);
        }       
    }
   
    public static void main(String args[]) {        
        Pizza pizza=new Pizza.Builder().pizzacrust(3.5).cheese(2.5).greenOlivesToppings(.7).build();
         System.out.println(pizza);
    }
}

Disadvantages of Builder Design pattern
is verbose and code duplication as Builder needs to copy all fields from Original or Item class.

Advantages
of Builder Design pattern are:
1). more maintainable if number of fields required to create object is more than 4 or 5.
2). less error-prone as user will know what they are passing because of explicit method call.
3). more robust as only fully constructed object will be available to client.
 


A class instance can be created using new operator. Why should we use creational design patterns to create objects?
Using new operator to create objects is a valid approach but it's like hard coding the object type. If we are 100% sure that our object will be of the same class all the time, then we use new operator to create an object. In scenarios where the nature of the object can change according to the nature of the program, we use creational design patterns which offer flexible approach for creating class instances

Which design pattern is used to get a way to access the elements of a collection object in sequential manner?
Iterator pattern is used to get a way to access the elements of a collection object in sequential manner.

When service locator pattern is used?
When we want to locate various services using JNDI we use service locator pattern.

Mention which design pattern will be helpful to add new functionality to an existing object?
A decorator pattern allows a user to add new functionality to an existing object without changing its structure.

Mention which pattern is useful when one has to pass data with multiple attributes in one shot from client to server?

Transfer Object Pattern is useful when one has to pass data with multiple attributes in one shot from client to the server.

What is SOLID principle in Java?
1). Single Responsibility Principle : One class should have one and only one responsibility. We should write, change and maintain a class for only one purpose.
2). Open Closed Principle : Software components should be open for extension, but closed for modification. It means that your classes should be designed such a way that whenever fellow developers wants to change the flow of control in specific conditions in application, all they need to extend your class and override some functions and that’s it. If other developers are not able to design desired behavior due to constraints put by your class, then you should reconsider changing your class.
3). Liskov’s Substitution Principle : Derived types must be completely substitutable for their base types. It means that the classes fellow developer created by extending your class should be able to fit in application without failure. i.e. if a fellow developer poorly extended some part of your class and injected into framework/ application then it should not break the application or should not throw fatal exceptions.
4). Interface Segregation Principle : It is applicable to interfaces as single responsibility principle holds to classes. Clients should not be forced to implement unnecessary methods which they will not use. e.g: If you created an interface Reportable and added two methods generateExcel() and generatedPdf(). Now another developer wants to use this interface but he intend to use reports only in PDF format and not in excel. He will have to implement two methods, out of which one is extra burden put on him by designer of software. Either he will implement another method or leave it blank. Which is wrong. Instead of one interface, we should create two interfaces by breaking the existing one. They should be like PdfReportable and ExcelReportable. This will give the flexibility to user to use only required functionality only.
5). Dependency Inversion Principle : Depend on abstractions, not on concretions. We should design our software in such a way that various modules can be separated from each other using an abstract layer to bind them together.

-K Himaanshu Shuklaa..

No comments:

Post a Comment

RSSChomp Blog Directory