Object Oriented Programming
BITS Pilani                 Dr. Tanmaya Mahapatra and Asish Bera
                             Computer Science & Information Systems
Pilani Campus
                             BITS Pilani
                          Pilani Campus
Design Patterns in Java
(Module- 10a)
Introduction
In the late 70’s (1977), an architect named Christopher Alexander started the concept of patterns.
Christopher had said that “Each pattern describes a problem that occurs over and over again in
our environment, and then describes the core of the solution to that problem, in such a way
that you can use this solution a million times over, without ever doing it the same way twice”.
Later, the Gang of Four - Design patterns, elements of reusable object-oriented software book
  was written by a group of four persons named as Erich Gamma, Richard Helm, Ralph Johnson
  and John Vlissides in 1995.
That's why all the above 23 Design Patterns are known as Gang of Four (GoF) Design Patterns.
   As an Object Oriented developer, we may think that our code contains all the benefits provided by
   the Object Oriented language.
   The code we have written is flexible enough that we can make any changes to it easily.
   Our code is re-usable so that we can re-use it anywhere without any trouble.
   We can maintain our code easily and any changes to a part of the code will not affect any other
   part of the code.
                                                                                            BITS Pilani, Pilani Campus
Contd…
 reusable in multiple projects.
 capture the software engineering experiences.
 provide transparency to the design of an application.
 well-proved and testified solutions since they have been built upon the knowledge and
  experience of expert software developers.
 don’t guarantee an absolute solution to a problem.
 provide the solutions that help to define the system architecture.
 provide clarity to the system architecture and the possibility of building a better system.
                                                                                   BITS Pilani, Pilani Campus
Categories
1.Creational Design Pattern (object creation)
                                                               3. Behavioural Design Pattern
                                                                         (class/object interaction)
a.   Factory Pattern
b.   Abstract Factory Pattern                                  a.   Chain Of Responsibility Pattern
                                                               b.   Command Pattern
c.   Singleton Pattern                                         c.   Interpreter Pattern
d.   Prototype Pattern     2. Structural Design Pattern        d.   Iterator Pattern
                           (composition of class and object)   e.   Mediator Pattern
e.   Builder Pattern                                           f.   Memento Pattern
                                a.   Adapter Pattern           g.   Observer Pattern
                                b.   Bridge Pattern            h.   State Pattern
                                c.   Composite Pattern         i.   Strategy Pattern
                                d.   Decorator Pattern         j.   Template Pattern
                                e.   Facade Pattern            k.   Visitor Pattern
                                f.   Flyweight Pattern
                                g.   Proxy Pattern
                                                                                              BITS Pilani, Pilani Campus
                                        BITS Pilani
                                     Pilani Campus
Creational Design Patterns in Java
(Module- 10a)
Creational Design Pattern
Creational design patterns are concerned with the way of creating objects.
   These design patterns are used when a decision must be made at the time of
   instantiation of a class (i.e. creating an object of a class).
1. Singleton Pattern
   The singleton pattern restricts the instantiation of a Class and ensures that
   only one instance of the class exists in the JVM.
2. Factory Pattern
• The factory design pattern is used when, we have a superclass with multiple
   subclasses and based on input, we need to return one of the subclasses.
• This pattern takes out the responsibility of the instantiation of a Class from the
   client program to the factory class. We can apply a singleton pattern on the
   factory class or make the factory method static.
                                                                            BITS Pilani, Pilani Campus
Factory Pattern
• A Factory Pattern says that just define an interface or abstract class for
  creating an object, but let the subclasses decide which class to
  instantiate. In other words, subclasses are responsible to create the instance
  of the class.
• Factory Pattern allows the sub-classes to choose the type of objects to create.
• It promotes the loose-coupling by eliminating the need to bind application-
  specific classes into the code.
• The code interacts solely with the resultant interface or abstract class, so that
  it will work with any classes that implement that interface or extends the
  abstract class.
                                                                           BITS Pilani, Pilani Campus
Abstract Factory and Builder Patterns
3. Abstract Factory Pattern
   It solves the problem of creating entire product families without specifying their
   concrete classes.
   It is similar to the factory pattern and is a factory of factories. If you are
   familiar with the factory design pattern in Java, you will notice that we have a
   single factory class. In the abstract factory pattern, we have a factory class for
   each subclass, and then an abstract factory class that will return the subclass
   based on input factory class.
4. Builder Pattern
   It was introduced to solve some of problems with Factory and Abstract Factory
   patterns, when the object contains a lot of attributes.
   It solves the issue with a large number of optional parameters and inconsistent
   state by providing a way to build the object step-by-step and provide a method
   that will actually return the final Object.
                                                                            BITS Pilani, Pilani Campus
 Singleton Pattern
Singleton pattern is one of the simplest design
patterns.
It 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.
                                                            BITS Pilani, Pilani Campus
    Contd…
public class SingleObject {
 //create an object of SingleObject
 private static SingleObject instance = new SingleObject();
    // private constructor so that the class cannot be instantiated
    private SingleObject(){ }
    //Get the only object available                 public class SingletonPatternDemo {
    public static SingleObject getInstance(){         public static void main(String[ ] args) {
      return instance;                               SingleObject object = SingleObject.getInstance();
    }                                                       object.showMessage();
    public void showMessage(){                        }
      System.out.println("Hello World!");           }
                                                                               Hello World!
    }
}
                                                                                              BITS Pilani, Pilani Campus
 Factory Pattern
Creates object without exposing the creation
logic to the client, and refer to newly created
object using a common interface.
  public interface Shape { void draw(); }
public class Rectangle implements Shape {
public void draw() {
System.out.println("Inside Rectangle:draw() method");
 }}
public class Square implements Shape {public void draw() {
System.out.println("Inside Square::draw() method."); } }
 public class Circle implements Shape {
 public void draw() { System.out.println("Inside Circle::draw() method."); }
 }
                                                                               BITS Pilani, Pilani Campus
  Contd …
public class ShapeFactory {
  //use getShape method to get object of type shape      public class FactoryPatternDemo {
  public Shape getShape(String shapeType){                 public static void main(String[ ] args) {
    if(shapeType == null){                                   ShapeFactory shapeFactory = new ShapeFactory();
                                                             //get an object of Circle and call its draw method.
       return null;  }
                                                             Shape shape1 = shapeFactory.getShape("CIRCLE");
    if(shapeType.equalsIgnoreCase("CIRCLE")){                        shape1.draw();      //call draw method of Circle
       return new Circle();                                  //get an object of Rectangle and call its draw method.
    } else if(shapeType.equalsIgnoreCase("RECTANGLE"))       Shape shape2 = shapeFactory.getShape("RECTANGLE");
    { return new Rectangle();                                        shape2.draw(); //call draw method of Rectangle
                                                             //get an object of Square and call its draw method.
    } else if(shapeType.equalsIgnoreCase("SQUARE")){
                                                             Shape shape3 = shapeFactory.getShape("SQUARE");
       return new Square();                                  //call draw method of square
    }                                                        shape3.draw();
    return null;                                           }
  }                                                      }
}
                                                                                                     BITS Pilani, Pilani Campus
 Abstract Factory Pattern
//3 Create an Abstract
class to get                                                        // Step 6 Use FactoryProducer to
factories                                                           get AbstractFactory to get factories
 for both                                                           of concrete classes
Shape Objects.
                                                  // Step 5 Create a Factory producer
           // 4 Create Factory                     class to get factories
           classes extending
           AbstractFactory to
            generate object of
           concrete class        //1 Create an interface for Shapes
                                             https://www.tutorialspoint.com/design_pattern/abstract_factory_pattern.htm
                                         //2 Create concrete class implementing Shape interface.
                                                                                               BITS Pilani, Pilani Campus
Implementation
//1 Create an interface for Shapes.
public interface Shape {
  void draw();
}
//2 Create concrete class implementing Shape interface.
public class RoundedRectangle implements Shape {
public void draw() {
    System.out.println("Inside RoundedRectangle::draw() method.");
  }
}
//3 Create an Abstract class to get factories for both Shape Objects.
public abstract class AbstractFactory {
  abstract Shape getShape(String shapeType) ;
}
                                                                        BITS Pilani, Pilani Campus
    Contd …
// 4 Create Factory classes extending AbstractFactory to generate object of concrete class
    based on given information.
public class ShapeFactory extends AbstractFactory {
public Shape getShape(String shapeType){
        if(shapeType.equalsIgnoreCase("RECTANGLE"))     public class RoundedShapeFactory extends AbstractFactory {
        {       return new Rectangle();     }           public Shape getShape(String shapeType){
        else if(shapeType.equalsIgnoreCase("SQUARE"))           if(shapeType.equalsIgnoreCase("RECTANGLE")){
        {      return new Square();     }                          return new RoundedRectangle();
        return null;                                            }else if(shapeType.equalsIgnoreCase("SQUARE")){
    }                                                              return new RoundedSquare();
}                                                               }
                                                                return null;
                                                            }
                                                        }
                                                                                                   BITS Pilani, Pilani Campus
Contd …
// Step 5 Create a Factory generator/producer class to get factories by passing
   an information such as Shape
public class FactoryProducer {
 public static AbstractFactory getFactory(boolean rounded){
   if(rounded){
      return new RoundedShapeFactory();
   }else{
      return new ShapeFactory();
   }
 }
                                                                          BITS Pilani, Pilani Campus
Contd …
// Step 6 Use FactoryProducer to get AbstractFactory to get factories of concrete classes by passing type information
public class AbstractFactoryPatternDemo {
 public static void main(String[ ] args) {
  AbstractFactory shapeFactory = FactoryProducer.getFactory(false); //get shape factory
  Shape shape1 = shapeFactory.getShape("RECTANGLE");         //get an object of Shape Rectangle
        //call draw method of Shape Rectangle
        shape1.draw();                   //get an object of Shape Square
        Shape shape2 = shapeFactory.getShape("SQUARE");
        shape2.draw();            //call draw method of Shape Square
        //get shape factory
        AbstractFactory shapeFactory1 = FactoryProducer.getFactory(true); //get an object of Shape Rectangle
        Shape shape3 = shapeFactory1.getShape("RECTANGLE"); //call draw method of Shape Rectangle
        shape3.draw();               //get an object of Shape Square
        Shape shape4 = shapeFactory1.getShape("SQUARE");
        shape4.draw();    //call draw method of Shape Square
    }
}
                                                                                                       BITS Pilani, Pilani Campus
Prototype Design Pattern
It is a creational design pattern. Cloning of an existing object instead of
    creating new one and can also be customized as per the requirement.
Prototype patterns are required, when object creation is time consuming, and
    costly operation, so we create objects with the existing object itself.
One of the best available ways to create an object from existing objects is
    the clone() method.
Deep Copy vs. Shallow Copy: The Prototype pattern raises the issue of
    whether to perform a deep copy or a shallow copy when cloning objects.
A shallow copy may result in objects sharing references to the same underlying
    data, leading to unintended side effects.
A deep copy can be resource-intensive and may require implementing custom
    cloning logic for all associated objects.
                                                                        BITS Pilani, Pilani Campus
Example
          BITS Pilani, Pilani Campus
BasicCar
import java.util.Random;
   public abstract class BasicCar implements Cloneable{
   public String modelName;
   public int basePrice,onRoadPrice;
   public String getModelname() {
   return modelName; }
   public void setModelname(String modelname) {
   this.modelName = modelname; }
   public static int setAdditionalPrice()
   {
   int price = 0;
   Random r = new Random();
   //We will get an integer value in the range 0 to 100000
   int p = r.nextInt(100000);
   price = p;
   return price;
   }
   public BasicCar clone() throws CloneNotSupportedException
   {return (BasicCar)super.clone(); }
   }
                                                               BITS Pilani, Pilani Campus
class Nano extends BasicCar
   {
   //A base price for Nano
   public int basePrice=100000;
   public Nano(String m)
   {
        modelName = m;
   }
   public BasicCar clone() throws CloneNotSupportedException
   {
        return (Nano)super.clone();
   }
   }
                                                               BITS Pilani, Pilani Campus
class Ford extends BasicCar
   {
   public int basePrice=100000;
   public Ford(String m)
   {
       modelName = m;}
       public BasicCar clone() throws CloneNotSupportedException
   {
       return (Ford)super.clone();
   }
   }
                                                                   BITS Pilani, Pilani Campus
public class PrototypePatternExample {
  public static void main(String[ ] args) throws
  CloneNotSupportedException {                                 Car is: Green Nano and it's price is
  System.out.println("***Prototype Pattern Demo***\n");        Rs.123806
  BasicCar nano = new Nano("Green Nano") ;                     Car is: Ford Yellow and it's price is
  nano.basePrice=100000;                                       Rs.595460
  BasicCar ford = new Ford("Ford Yellow");
  ford.basePrice=500000;
  BasicCar bc1;
  bc1 =nano.clone(); //Nano
  bc1.onRoadPrice = nano.basePrice+BasicCar.setAdditionalPrice();
  System.out.println("Car is: "+ bc1.modelName+" and it's price is
  Rs."+bc1.onRoadPrice);
  bc1 =ford.clone(); //Ford
  bc1.onRoadPrice = ford.basePrice+BasicCar.setAdditionalPrice();
  System.out.println("Car is: "+ bc1.modelName+" and it's price is
  Rs."+bc1.onRoadPrice); }
  }
                                                                                         BITS Pilani, Pilani Campus
Builder design pattern
Builder — A creational design pattern that lets you construct
   complex objects step by step. The pattern allows you to produce
   different types and representations of an object using the same
   construction code.
Builder design pattern consists of components such as builder
   interface, concrete builders, product, and client.
Product is the complex object that you want to create.
ConcreteBuilder constructs and assembles the parts of a product
by implementing an abstract interface Builder.
ConcreteBuilder objects build the product’s internal representation
   and define the creational process/assembling mechanisms.
Builders can also provide methods to get an object that is created and
   available for use.
Director is responsible for creating final object using Builder interface.
   Director uses Builder and controls the steps/sequence to build the
   final Product. Builders can also keep reference of the products that
   they built, so that they can be used again.
                                                                             BITS Pilani, Pilani Campus
Example
          BITS Pilani, Pilani Campus
interface Builder
   {
   void startUpOperations();
   void buildBody();
   void insertWheels();
   void addHeadlights();
   void endOperations();
   /*The following method is used to retrieve the object that is constructed.*/
   Product getVehicle();
   }
                                                                            BITS Pilani, Pilani Campus
                                                   public void buildBody()
                                                   {product.add("This is a body of a Car");}
class Car implements Builder
   {                                               public void insertWheels()
   private String brandName;                       {product.add("4 wheels are added");}
   private Product product;                        public void addHeadlights()
   public Car(String brand)                        {product.add("2 Headlights are added");}
   {
   product = new Product();
                                                   public void endOperations()
   this.brandName = brand;                         { //Nothing in this case}
   }                                               public Product getVehicle()
   public void startUpOperations()                 {return product;}
   {                                               }
   //Starting with brand name
   product.add(String.format("Car model is :%s",this.brandName));
   }
                                                                                BITS Pilani, Pilani Campus
Product class
class Product
   { /* You can use any data structure that you prefer. */
   private LinkedList<String> parts;
   public Product()
   {parts = new LinkedList<String>();
   }
   public void add(String part)
   { //Adding parts
        parts.addLast(part);
   }
   public void showProduct()
   {    System.out.println("\nProduct completed as below :");
        for (String part: parts)
        System.out.println(part);
   }
   }
                                                                BITS Pilani, Pilani Campus
Director class
class Director
   {Builder builder;
   // Director knows how to use the builder and the sequence of steps.
   public void construct(Builder builder)
   {
   this.builder = builder;
   builder.startUpOperations();
   builder.buildBody();
   builder.insertWheels();
   builder.addHeadlights();
   builder.endOperations();
   }
   }
                                                                         BITS Pilani, Pilani Campus
public class BuilderPatternExample {
  public static void main(String[ ] args) {
  System.out.println("***Builder Pattern Demo***");
  Director director = new Director();
  Builder fordCar = new Car("Ford");
  Builder hondaMotorycle = new MotorCycle("Honda");
  director.construct(fordCar);
  Product p1 = fordCar.getVehicle();
  p1.showProduct();
  director.construct(hondaMotorycle ); //Making MotorCycle
  Product p2 = hondaMotorycle.getVehicle();
  p2.showProduct();
  }}
                                                             BITS Pilani, Pilani Campus
Example
          BITS Pilani, Pilani Campus
 Builder Example
public class Employee {                                    public static class EmployeeBuilder {
  private String name;                                       private String name;
  private String company;                                    private String company;
                                                             private boolean hasCar;//optional
  private boolean hasCar;//optional                          private boolean hasBike;//optional
  private boolean hasBike;//optional                         //constructor for required fields
  private Employee(EmployeeBuilder employeeBuilder) {        public EmployeeBuilder(String name, String company) {
    name = employeeBuilder.name;                               this.name = name;
    company = employeeBuilder.company;                         this.company = company;         }
    hasCar = employeeBuilder.hasCar;                         //setter methods for optional fields
    hasBike = employeeBuilder.hasBike;                       public EmployeeBuilder setHasCar(boolean hasCar) {
                                                               this.hasCar = hasCar;
  }                                                            return this;      }
  public String getName() {                                  public EmployeeBuilder setHasBike(boolean hasBike) {
    return name; }                                             this.hasBike = hasBike;
  public String getCompany() {                                 return this;      }
    return company;                                          //Build the Employee object
  }                                                          public Employee build() {       return new Employee(this);  } }}
  public boolean isHasCar() {                           class TestBuilder {
                                                           public static void main(String[] args) {
    return hasCar; }                                         //Building the object of Employee thru build() method in EmployeeBuilder class.
  public boolean isHasBike() {                               Employee employee = new Employee.EmployeeBuilder("Vikram",
    return hasBike; }                                   "ABC").setHasBike(false).setHasBike(true).build();
                                                           }
                                                        }
                                                                                                                           BITS Pilani, Pilani Campus
                                        BITS Pilani
                                     Pilani Campus
Structural Design Patterns in Java
(Module- 10b)
 Adapter Pattern
Converts the interface of a class into another interface that a client wants.
• Provides an interface according to client requirement while using the services
  of a class with a different interface.
• Allows two or more incompatible objects to interact.
• Allows reusability of existing functionality.
• The adapter translates that request on the adaptee using the adaptee interface.
• Client receive the results of the call and is unaware of adapter’s presence.
• Client requests to the adapter by calling a method on it using target interface.
                                                                           BITS Pilani, Pilani Campus
Specifications of Adapter pattern
Target Interface: This is the desired interface class which
will be used by the clients.
Adapter class: This class is a wrapper class which
implements the desired target interface and modifies
the specific request available from the Adaptee class.
Adaptee class: This class is used by the Adapter class to
reuse the existing functionality and modify them for
desired use.
Client: This class will interact with the Adapter class.
                                                              BITS Pilani, Pilani Campus
Example
interface Bird
{ // birds implement Bird interface that allows them to fly and make sounds adaptee interface
    public void fly();
    public void makeSound();                        Problem: Suppose you have a Bird class with fly() ,
}                                                   and makeSound()methods. And also a ToyDuck class
class Sparrow implements Bird                       with squeak() method. Let’s assume that you are
{ // a concrete implementation of bird              short on ToyDuck objects and you would like to use
    public void fly()                               Bird objects in their place.
    {    System.out.println("Flying");     }        Birds have some similar functionality but implement
    public void makeSound()                         a different interface, so we can’t use them directly. So
    {    System.out.println("Chirp Chirp"); }       we will use adapter pattern. Here our client would be
}                                                   ToyDuck and adaptee would be Bird.
interface ToyDuck
{ // target interface toyducks dont fly they just make squeaking sound
    public void squeak();
}
                                                                                              BITS Pilani, Pilani Campus
Code
                                                   class Main{
class PlasticToyDuck implements ToyDuck{           public static void main(String args[])     {
   public void squeak()
                                                   Sparrow sparrow = new Sparrow();
   {      System.out.println("Squeak");}
                                                   ToyDuck toyDuck = new PlasticToyDuck();
}
class BirdAdapter implements ToyDuck
                                                   // Wrap a bird in a birdAdapter so that it
{ // You need to implement the interface your      // behaves like toy duck
   // client expects to use.                       ToyDuck birdAdapter = new BirdAdapter(sparrow);
   Bird bird;                                      System.out.println("Sparrow...");
   public BirdAdapter(Bird bird) {                 sparrow.fly();
          // we need reference to the object we    sparrow.makeSound();
          // are adapting                          System.out.println("ToyDuck...");
          this.bird = bird; }                      toyDuck.squeak();
   public void squeak()                            // toy duck behaving like a bird
   {                                               System.out.println("BirdAdapter...");
          // translate the methods appropriately   birdAdapter.squeak();       }
          bird.makeSound();         }              }
}
                                                                                   BITS Pilani, Pilani Campus
 Facade Pattern
• Just provide a unified and simplified interface to a
  set of interfaces
• In a subsystem, it hides the complexities of the
  subsystem from the client.
• Every Abstract Factory is a type of Facade.
• It shields the clients from the complexities of the
  sub-system components.
• It promotes loose coupling between subsystems and
  its clients.
                                                         BITS Pilani, Pilani Campus
Example
          BITS Pilani, Pilani Campus
Basic Steps
//1 Create a MobileShop interface.
public interface MobileShop {
   public void modelNo();
   public void price();
}
//2 Create a Iphone implementation class that will implement Mobileshop interface.
public class Iphone implements MobileShop {
    public void modelNo() {
     System.out.println(" Iphone ");
   }                                                     Similarly, create the classes for
    public void price() {                                Samsung and Other Brands
   System.out.println(" Rs 85000 ");
   }
}
                                                                                 BITS Pilani, Pilani Campus
//3 Create a ShopKeeper concrete class that will use MobileShop interface.
public class ShopKeeper {
  private MobileShop iphone;
  private MobileShop samsung;
  private MobileShop blackberry;
    public ShopKeeper(){
      iphone= new Iphone();
      samsung=new Samsung();
      blackberry=new Blackberry();
    }
      public void iphoneSale(){     iphone.modelNo();        iphone.price();    }
      public void samsungSale(){      samsung.modelNo();         samsung.price();     }
      public void blackberrySale(){    blackberry.modelNo();    blackberry.price();       }
}
                                                                                          BITS Pilani, Pilani Campus
                                                                                 switch (choice) {
//4 Create a client for buying the mobiles from MobileShop through ShopKeeper.
import java.io.BufferedReader;                                                         case 1:
import java.io.IOException;                                                               { sk.iphoneSale();       }
import java.io.InputStreamReader;                                                         break;
                                                                                    case 2:
public class FacadePatternClient {                                                        { sk.samsungSale();       }
 private static int choice;                                                               break;
 public static void main(String args[ ]) throws                                     case 3:
NumberFormatException, IOException{                                                          { sk.blackberrySale(); }
   do{                                                                                      break;
       System.out.print("========= Mobile Shop ============ \n");                      default: {
       System.out.print("        1. IPHONE.        \n");                               System.out.println(“Default");
       System.out.print("        2. SAMSUNG.          \n");                            }
       System.out.print("        3. BLACKBERRY.          \n");                            return; }
       System.out.print("        4. Exit.       \n");                              }while(choice!=4); } }
       System.out.print("Enter your choice: ");
     BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
     choice=Integer.parseInt(br.readLine());
      ShopKeeper sk=new ShopKeeper();
                                                                                                    BITS Pilani, Pilani Campus
Example
          BITS Pilani, Pilani Campus
Decorator Design Pattern
Decorator design pattern allows to add a property to an object in a dynamically, without
  having to change the implementation of that object.
The decorator is considered as Structural design pattern, and follows the Open-
  Closed Principle which provides a wrapper to the existing class.
The decorator design pattern uses abstract classes or interfaces with the composition
  to implement the wrapper.
Steps:
• Create an interface, and create concrete classes implementing the same interface.
• Create an abstract decorator class implementing the above same interface.
• Create a concrete decorator class extending the above abstract decorator class.
• Now use the concrete decorator class created above to decorate interface objects.
                                                                                 BITS Pilani, Pilani Campus
Example: Decorator Pattern
                             BITS Pilani, Pilani Campus
Code
//1 Interface named Shape                     //3 Class 2
public interface Shape {                      // Abstract class
                                              public abstract class ShapeDecorator implements Shape {
   public void draw();
                                                       protected Shape decoratedShape;
}                                                      // Abstract class method
                                                       public ShapeDecorator(Shape decoratedShape)
// 2                                                   {
public class Circle implements Shape {                   this.decoratedShape = decoratedShape;
                                                       }
    public void draw()
                                                       // Method 2 - draw()
    {    System.out.println("Shape: Circle");          // Outside abstract class
    }                                                  public void draw() { decoratedShape.draw(); }
}                                             }
                                                                                           BITS Pilani, Pilani Campus
Contd
// 4 Class 3
// Concrete class extending the abstract class
public class RedShapeDecorator extends ShapeDecorator {
    public RedShapeDecorator(Shape decoratedShape)
    {
          super(decoratedShape);
    }
    {
          decoratedShape.draw();
          setRedBorder(decoratedShape);
    }
    private void setRedBorder(Shape decoratedShape)
    {
          System.out.println("Border Color: Red");
    }
}
                                                          BITS Pilani, Pilani Campus
Contd
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());
         System.out.println("Circle with normal border");
         circle.draw();
         System.out.println("\nCircle of red border");
         redCircle.draw();
         System.out.println("\nRectangle of red border");
         redRectangle.draw();
  }
}
                                                                       BITS Pilani, Pilani Campus
Flyweight Design Pattern
Flyweight design pattern is used when we need to create a lot of Objects of a class.
   Since every object consumes memory space that can be crucial for low memory
   devices, such as mobile devices or embedded systems, flyweight design pattern
   can be applied to reduce the load on memory by sharing objects.
Use sharing to support large numbers of fine-grained objects efficiently.
A flyweight object essentially has intrinsic and extrinsic attributes.
An intrinsic state attribute is stored/shared in the flyweight object, and it is
   independent of flyweight’s context. We should make intrinsic states immutable.
An extrinsic state varies with flyweight’s context, which cannot be shared.
Client objects maintain the extrinsic state, and they need to pass this to a flyweight
   object during object creation.
                                                                           BITS Pilani, Pilani Campus
Major Components
The Flyweight Design Pattern involves the following key components:
Flyweight Interface : This is the interface that declares methods common to all
   concrete flyweights. It may include methods for setting or getting intrinsic state.
Concrete Flyweight : This is the concrete implementation of the flyweight interface. It
   contains the intrinsic state that is shared among multiple objects.
Unshared Concrete Flyweight : In some cases, not all flyweights can be shared. The
   unshared concrete flyweight represents objects with unshareable intrinsic state.
Flyweight Factory: : This is responsible for managing flyweight objects and ensuring
   that they are shared properly. It may include methods for creating or retrieving
   flyweights.
Client : The client is responsible for using flyweights. It maintains the extrinsic state,
   which is not shared among flyweights.
                                                                                   BITS Pilani, Pilani Campus
Example
          BITS Pilani, Pilani Campus
 Contd.
                                    public class RailwayTicket implements Ticket {
                                      private String type;
public interface Ticket {             private int fare;
  public void setName(String name);   private String name;
                                       public RailwayTicket(String type){
  public void setFare(int fare);        this.type = type; }
  public void printTicket();           public void setName(String name){
                                        this.name = name; }
}                                      public void setFare(int fare){
                                        this.fare = fare; }
                                    public void printTicket(){
                                        System.out.println("--------TICKET--------");
                                        System.out.println("Name : "+ name + "\nTicket Type : "
                                           + type + "\nFare : " + fare); }
                                    }
                                                                                   BITS Pilani, Pilani Campus
Contd.
import java.util.Map;
import java.util.HashMap;
public class TicketFactory {
  private static Map<String, Ticket> ticketMap = new HashMap<String, Ticket>();
  public static Ticket getTicket(String type, String name, int fare){
     Ticket ticket;
     if(ticketMap.containsKey(type)){
         ticket = ticketMap.get(type);
     } else {
         ticket = new RailwayTicket(type);
         ticketMap.put(type, ticket);
     }
     ticket.setName(name);
     ticket.setFare(fare);
      return ticket;
  }
}
                                                                                  BITS Pilani, Pilani Campus
Contd.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class TicketBookingSystem {
public static void main(String args[ ]) throws IOException{
 BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
 Ticket ticket;
 for(int i=0; i < 5; i++){
    System.out.println("Enter ticket type, Name and Fare");
    String[ ] stringList = br.readLine().split(" ");
    ticket = TicketFactory.getTicket(stringList[0], stringList[1], Integer.parseInt(stringList[2]));
    ticket.printTicket();
 }
   }
}
                                                                                                 BITS Pilani, Pilani Campus
Proxy Design Pattern
In proxy pattern, a class represents functionality of another class. This type of
   design pattern comes under structural pattern.
In proxy pattern, we create object having original object to interface its functionality
   to outer world.
Create an Image interface and concrete classes implementing the Image interface.
ProxyImage is a proxy class to reduce memory footprint of RealImage object
   loading.
ProxyPatternDemo, our demo class, will use ProxyImage to get an Image object to
   load and display as it needs.
                                                                              BITS Pilani, Pilani Campus
Example
          BITS Pilani, Pilani Campus
public interface Image {
  void display();
}
public class RealImage implements Image {
  private String fileName;
  public RealImage(String fileName){
    this.fileName = fileName;
    loadFromDisk(fileName);
  }
public void display() {
    System.out.println("Displaying " + fileName);
  }
  private void loadFromDisk(String fileName){
    System.out.println("Loading " + fileName);
  }
}
                                                    BITS Pilani, Pilani Campus
Contd.
public class ProxyImage implements Image{
  private RealImage realImage;
  private String fileName;
                                              public class ProxyPatternDemo {
 public ProxyImage(String fileName){             public static void main(String[] args) {
   this.fileName = fileName;                    Image image = new ProxyImage("test_10mb.jpg");
 }                                                       image.display();
                                                   System.out.println("");
public void display() {                                  image.display();
    if(realImage == null){                       }
                                              }
       realImage = new RealImage(fileName);
    }
    realImage.display();
  }
}
                                                                              BITS Pilani, Pilani Campus
                                        BITS Pilani
                                     Pilani Campus
Behavioral Design Patterns in Java
(Module- 10c)
Observer Pattern
An Observer Pattern says that "just define a one-to-one dependency so that
    when one object changes state, all its dependents are notified and updated
    automatically".
The observer pattern is also known as Dependents or Publish-Subscribe.
It describes the coupling between the objects and the observer.
It provides the support for broadcast-type communication.
                                                                         BITS Pilani, Pilani Campus
Example
          BITS Pilani, Pilani Campus
Contd..
import java.util.Observable;
import java.util.Observer;
public class ResponseHandler1 implements Observer {
    private String resp;
    public void update(Observable obj, Object arg) {
      if (arg instanceof String) {
          resp = (String) arg;
          System.out.println("\nReceived Response: " + resp );
      }
    }
}// End of the ResponseHandler1 interface.
                                                                 BITS Pilani, Pilani Campus
Contd..
import java.util.Observable;
import java.util.Observer;
public class ResponseHandler2 implements Observer {
    private String resp;
    public void update(Observable obj, Object arg) {
      if (arg instanceof String) {
          resp = (String) arg;
          System.out.println("\nReceived Response: " + resp );
      }
    }
}// End of the ResponseHandler2 interface.
                                                                 BITS Pilani, Pilani Campus
Contd..
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Observable;
public class EventSource extends Observable implements Runnable {
 public void run() {
      try {
         final InputStreamReader isr = new InputStreamReader(System.in);
         final BufferedReader br = new BufferedReader(isr);
         while (true) {
            String response = br.readLine();
            setChanged();
            notifyObservers(response); }
      }
      catch (IOException e) { e.printStackTrace(); }
    }
}// End of the Eventsource class.
                                                                           BITS Pilani, Pilani Campus
State Design pattern
State pattern is to allow the object for changing its behavior without changing
  its class.
Context class has an associated State which is going to
change during program execution.
Our context is going to delegate the behavior to the
state implementation.
In other words, all incoming requests will be handled by
the concrete implementation of the state.
Logic is separated and adding new states is simple.
It comes down to adding another State implementation if
needed.
Improves Cohesion since state-specific behaviors are
aggregated into the ConcreteState classes, which are
placed in one location in the code block.
                                                                      BITS Pilani, Pilani Campus
Example
              public interface State {
                public void doAction(Context context);
              }
          public class StartState implements State {
              public void doAction(Context context) {
                System.out.println("Player is in start state");
                context.setState(this);
              }
              public String toString(){
                return "Start State";
              }
          }
                                                   BITS Pilani, Pilani Campus
Contd..
public class StopState implements State {
  public void doAction(Context context) {            public class Context {
                                                       private State state;
    System.out.println("Player is in stop state");
                                                       public Context(){
    context.setState(this);                              state = null;
  }                                                    }
  public String toString(){                            public void setState(State state){
    return "Stop State";                                 this.state = state;
                                                       }
  }
                                                       public State getState(){
}                                                        return state;
                                                       }
                                                     }
                                                                             BITS Pilani, Pilani Campus
Contd..
public class StatePatternDemo {
 public static void main(String[] args) {
   Context context = new Context();
        StartState startState = new StartState();
        startState.doAction(context);
        System.out.println(context.getState().toString());
        StopState stopState = new StopState();
        stopState.doAction(context);
        System.out.println(context.getState().toString());
    }
}
                                                             BITS Pilani, Pilani Campus
Exercise: Aircraft-State
                           BITS Pilani, Pilani Campus
Mediator Design Pattern
Mediator: defines the interface for communication between colleague objects.
ConcreteMediator: It implements the mediator interface and coordinates
  communication between colleague objects.
Colleague: It defines the interface for communication with other colleagues
ConcreteColleague: It implements the colleague interface and communicates
  with other colleagues through its mediator.
The intent of the Mediator Pattern is to reduce
the complexity and dependencies between
tightly coupled objects communicating directly
with one another.
Design the system in such a way that
components are loosely coupled and reusable.
                                                                       BITS Pilani, Pilani Campus
 Example: Mediator Pattern
•ApnaChatroom: defines the interface for
interacting with participants.
•ApnaChatroomImpl: implements the
operations defined by Chatroom interface.
The operations are managing the
interactions between the objects: when
one participant sends a message, the
message is sent to other participants.
•Participant: defines an interface for the
users involved in chatting.
•User1, User2, ...UserN: implements
Participant interface.
• the participant can be a number of users
involved in chatting. But each Participant
will keep only a reference to the
ApnaChatRoom.
                                             BITS Pilani, Pilani Campus
Contd…
public interface ApnaChatRoom {
  public void showMsg(String msg, Participant p); }
public class ApnaChatRoomImpl implements ApnaChatRoom{
  //get current date time
  DateFormat dateFormat = new SimpleDateFormat("E dd-MM-yyyy hh:mm a");
  Date date = new Date();
    public void showMsg(String msg, Participant p) {
     System.out.println(p.getName()+"'gets message: "+msg);
     System.out.println("\t\t\t\t"+"["+dateFormat.format(date).toString()+"]");
  }
}
                                                                              BITS Pilani, Pilani Campus
Contd..
public abstract class Participant {
  public abstract void sendMsg(String msg);
                                               public class User1 extends Participant {
  public abstract void setname(String name);       private String name;
  public abstract String getName();                private ApnaChatRoom chat;
                                                   public void sendMsg(String msg) {
}
                                                   chat.showMsg(msg,this);
                                                   }
                                                   public void setname(String name) {
                                                       this.name=name;
                                                   }
                                                   public String getName() {
                                                       return name;     }
                                                   public User1(ApnaChatRoom chat){
                                                       this.chat=chat;
                                                   }
                                               }
                                                                              BITS Pilani, Pilani Campus
Contd..
 public class MediatorPatternDemo {
     public static void main(String args[])
     {    ApnaChatRoom chat = new ApnaChatRoomImpl();
           User1 u1=new User1(chat);
           u1.setname("Aditya ");
           u1.sendMsg("Hi Rohit! how are you? What about Compre?");
          User2 u2=new User2(chat);
          u2.setname("Rohit");
          u2.sendMsg("I am Fine! How are you, Aditya? Going Slow..");
     }
                                                                        BITS Pilani, Pilani Campus
BITS Pilani, Pilani Campus
 BITS Pilani
Pilani Campus