Monday, June 25, 2012

Prototype Design Pattern

Introduction

Prototype design pattern is one of a creational design pattern. This pattern can be used when user wants to have an object but without instanciating it. That means using java clone feature. The advantage of this pattern is as you might know creating an object using new operator is very costly. But here we use clone method to create new objects. But you know if we want to create an object using clone method there should be existing object to make clone objects. So first object creation should be done by using the java new operator.

Example 

Suppose you want to draw some shapes. For example you want to draw shapes like Square, Triangle. But these drawing not only once. many times you want to draw Square and Triangle. In other words, you have to make instances of Square and Triangle classes. But you want to avoid that instance creation but make instances by cloning. So it is the prototype design pattern.

Following example code has Shape abstract class and Square and Triangle concrete classes. As you can see Shape class implement with Cloneable interface so that it can implement of cloning logic.

Shape.java

package com.blog.patterns.prototype;

/**
 * @author uditha
 */
public abstract class Shape implements Cloneable {

 public abstract void draw();
 
 @Override
 public Object clone() {
  Object clone = null;
  try {
   clone = super.clone();
  } catch (CloneNotSupportedException e) {
   e.printStackTrace();
  }
  return clone;
 }
 
}

Square.java

package com.blog.patterns.prototype;

/**
 * @author uditha
 */
public class Square extends Shape {

 @Override
 public void draw() {
  System.out.println("Square");
 }
 
}

Triangle.java

package com.blog.patterns.prototype;

/**
 * @author uditha
 */
public class Triangle extends Shape {

 @Override
 public void draw() {
  System.out.println("Triangle");
 }
 
}

Main.java

package com.blog.patterns.prototype;

/**
 * @author uditha
 */
public class Main {
 
 public static void main(String[] args) {
  Shape squareA = new Square();
  squareA.draw();
  Shape squareB = (Square) squareA.clone();
  squareB.draw();
  
  Shape triangleA = new Triangle();
  triangleA.draw();
  Shape triangleB = (Triangle) triangleA.clone();
  triangleB.draw();
 }

}

Wednesday, June 20, 2012

Builder Design Pattern

Introduction


Builder pattern is one of creational design pattern. It builds a complex object by building separated parts and finally integrates those parts and makes the complex object. But the construction logic is not visible to the user.

Example

Suppose you have to build a computer. But you also have to build computer parts such as processor, mother board, hard disk and RAM. So building all the parts finally integrate all the parts and build the final out put as computer (a desktop computer).  So this is the example I'm going to illustrate with java. Look at the following code and try to understand the concept of Builder design pattern of java.

Computer.java

package com.blog.patterns.builder;

/**
 * @author uditha
 */
public class Computer {

 private String processor;
 private String motherBoard;
 private String hardDisk;
 private String ram;

 public String getProcessor() {
  return processor;
 }

 public void setProcessor(String processor) {
  this.processor = processor;
 }

 public String getMotherBoard() {
  return motherBoard;
 }

 public void setMotherBoard(String motherBoard) {
  this.motherBoard = motherBoard;
 }

 public String getHardDisk() {
  return hardDisk;
 }

 public void setHardDisk(String hardDisk) {
  this.hardDisk = hardDisk;
 }

 public String getRam() {
  return ram;
 }

 public void setRam(String ram) {
  this.ram = ram;
 }
 
}

Builder.java

package com.blog.patterns.builder;

/**
 * @author uditha
 */
public interface Builder {

 public void buildProcessor();
 public void buildMotherBoard();
 public void buildHardDisk();
 public void buildRam();
 public Computer getComputer();
 
}

ComputerBuilder.java

package com.blog.patterns.builder;

/**
 * @author uditha
 */
public class ComputerBuilder implements Builder {
 
 private Computer computer;
 
 public ComputerBuilder() {
  computer = new Computer();
 }

 @Override
 public void buildProcessor() {
  computer.setProcessor("some processor");
 }

 @Override
 public void buildMotherBoard() {
  computer.setMotherBoard("some motherboard");
 }

 @Override
 public void buildHardDisk() {
  computer.setHardDisk("some hard disk");
 }

 @Override
 public void buildRam() {
  computer.setRam("some ram");
 }
 
 @Override
 public Computer getComputer() {
  return this.computer;
 }

}

Director.java

package com.blog.patterns.builder;

/**
 * @author uditha
 */
public class Director {
 
 public Computer buildComputer(Builder builder) {
  builder.buildProcessor();
  builder.buildMotherBoard();
  builder.buildHardDisk();
  builder.buildRam();
  return builder.getComputer();
 }

}

Main.java

package com.blog.patterns.builder;

/**
 * @author uditha
 */
public class Main {

 public static void main(String[] args) {
  Director director = new Director();
  Builder builder = new ComputerBuilder();
  Computer computer = director.buildComputer(builder);
  System.out.println(computer.getProcessor());
  System.out.println(computer.getMotherBoard());
  System.out.println(computer.getHardDisk());
  System.out.println(computer.getRam());
 }

}

Monday, June 18, 2012

Abstract Factory Pattern

Introduction


Abstract Factory Pattern can be defined as factory of factories. You can see the reason by looking at the example.

Example


Suppose you have 2 factories. Each factory makes phones and laptops. Suppose first factory is AppleFactory and other one is ToshibaFactory. AppleFactory makes IPhone and Mac laptop. ToshibaFactory makes ToshibaPhone and ToshibaLaptop. Let's see the code.

Phone.java


package com.blog.patterns.abstractfactory;

/**
 * @author uditha
 */
public abstract class Phone {

 public abstract String getCategory();
 
}

Laptop.java



package com.blog.patterns.abstractfactory;

/**
 * @author uditha
 */
public abstract class Laptop {

 public abstract String getOperatingSystem();
 
}

Factory.java


package com.blog.patterns.abstractfactory;

/**
 * @author uditha
 */
public interface Factory {

 public Phone createPhone();
 public Laptop createLaptop();
 
}

IPhone.java



package com.blog.patterns.abstractfactory;

/**
 * @author uditha
 */
public class IPhone extends Phone {

 @Override
 public String getCategory() {
  return "Mobile Phone";
 }
 
}

Mac.java



package com.blog.patterns.abstractfactory;

/**
 * @author uditha
 */
public class Mac extends Laptop {

 @Override
 public String getOperatingSystem() {
  return "Mac";
 }

}

AppleFactory.java

package com.blog.patterns.abstractfactory;

/**
 * @author uditha
 */
public class AppleFactory implements Factory {

 @Override
 public Phone createPhone() {
  return new IPhone();
 }

 @Override
 public Laptop createLaptop() {
  return new Mac();
 }

}

ToshibaPhone.java



package com.blog.patterns.abstractfactory;

/**
 * @author uditha
 */
public class ToshibaPhone extends Phone {

 @Override
 public String getCategory() {
  return "Land Phone";
 }
 
}

ToshibaLaptop.java



package com.blog.patterns.abstractfactory;

/**
 * @author uditha
 */
public class ToshibaLaptop extends Laptop {

 @Override
 public String getOperatingSystem() {
  return "Windows 7";
 }

}

ToshibaFactory.java



package com.blog.patterns.abstractfactory;

/**
 * @author uditha
 */
public class ToshibaFactory implements Factory {

 @Override
 public Phone createPhone() {
  return new ToshibaPhone();
 }

 @Override
 public Laptop createLaptop() {
  return new ToshibaLaptop();
 }

}

Main.java



package com.blog.patterns.abstractfactory;

/**
 * @author uditha
 */
public class Main {

 public static void main(String[] args) {
  // apple factory
  Factory factory = new AppleFactory();
  Phone phone = factory.createPhone();
  Laptop laptop = factory.createLaptop();
  System.out.println(phone.getCategory());
  System.out.println(laptop.getOperatingSystem());
  
  // toshiba factory
  factory = new ToshibaFactory();
  phone = factory.createPhone();
  laptop = factory.createLaptop();
  System.out.println(phone.getCategory());
  System.out.println(laptop.getOperatingSystem());
 }

}