Introduction
- Design patterns have evolved over a long period of time and they provide best solutions to certain problems faced during software development.
- These solutions were obtained by trial and error by numerous software developers over quite a substantial period of time.
- Design Principals are abstract ideas and Design Patterns are concrete implementations of those ideas.
Creational Design Pattern
1. SingleTone
Creates only one object:
class Singleton {
private static Singleton uniqueInstance;
private Singleton() {}
public static Singleton getInstance() {
if (uniqueInstance == null) {
uniqueInstance = new Singleton();
}
return uniqueInstance;
}
}
class SingletonPatternDemo {
public static void main(String[] args) {
Singleton object = Singleton.getInstance();
}
}
2. Factory Pattern
Encapsulate object creational logic – that varies.
interface IIceCream
{
string Functionality();
}
class ChocolateIceCream : IIceCream
{
public string Functionality()
{
return "Chocolate Ice cream";
}
}
class VanillaIceCream : IIceCream
{
public string Functionality()
{
return "Vanilla Ice cream";
}
}
class StrawberryIceCream : IIceCream
{
public string Functionality()
{
return "Strawberry Ice cream";
}
}
static class Factory
{
public static IIceCream Get(int id)
{
switch (id)
{
case 0:
return new ChocolateIceCream();
case 1:
return new VanillaIceCream();
case 2:
return new StrawberryIceCream();
default:
return null;
}
}
}
static void Main()
{
for (int i = 0; i <= 3; i++)
{
var type = Factory.Get(i);
if (type != null)
{
Console.WriteLine("This is Product : " + type.Functionality());
}
}
}
3.Abstract Factory
Factory of factories:
Real Example:
interface Animal{
void breath();
}
interface LandAnimal extends Animal {
void speak();
}
interface SeaAnimal extends Animal {
void swim();
}
class Cat implements LandAnimal {
@Override
public void speak() {
}
@Override
public void breath(){
}
}
class Dog implements LandAnimal {
@Override
public void speak() {
}
@Override
public void breath(){
}
}
class Lion implements LandAnimal {
@Override
public void speak() {
}
@Override
public void breath(){
}
}
class Shark implements SeaAnimal {
@Override
public void swim() {
}
@Override
public void breath(){
}
}
class Whale implements SeaAnimal {
@Override
public void swim() {
}
@Override
public void breath(){
}
}
class Octopus implements SeaAnimal {
@Override
public void swim() {
}
@Override
public void breath(){
}
}
abstract class AbstractFactory {
abstract Animal getAnimal(String type);
}
class LandAnimalFactory extends AbstractFactory {
@Override
public Animal getAnimal(String type) {
if (type == null) {
return null;
}
if (type.equalsIgnoreCase("LION")) {
return (Animal)new Lion();
} else if (type.equalsIgnoreCase("CAT")) {
return (Animal)new Cat();
} else if (type.equalsIgnoreCase("DOG")) {
return (Animal)new Dog();
}
return null;
}
}
class SeaAnimalFactory extends AbstractFactory {
@Override
Animal getAnimal(String type) {
if (type == null) {
return null;
}
if (type.equalsIgnoreCase("SHARK")) {
return (Animal)new Shark();
} else if (type.equalsIgnoreCase("WHALE")) {
return (Animal)new Whale();
} else if (type.equalsIgnoreCase("OCTOPUS")) {
return (Animal)new Octopus();
}
return null;
}
}
class FactoryProducer {
public AbstractFactory getFactory(String factoryType) {
if (factoryType.equalsIgnoreCase("LAND")) {
return new LandAnimalFactory();
} else if (factoryType.equalsIgnoreCase("SEA")) {
return new SeaAnimalFactory();
}
return null;
}
}
class AbstractFactoryPatternDemo {
public static void main(String[] args) {
FactoryProducer factoryProducer = new FactoryProducer();
AbstractFactory landAnimalFactory = factoryProducer.getFactory("LAND");
Animal dog = landAnimalFactory.getAnimal("DOG");
dog.speak();
dog.breath();
Animal cat = landAnimalFactory.getAnimal("CAT");
cat.speak();
cat.breath();
Animal lion = landAnimalFactory.getAnimal("LION");
lion.speak();
lion.breath();
AbstractFactory seaAnimalFactory = factoryProducer.getFactory("SEA");
Animal shark = seaAnimalFactory.getAnimal("SHARK");
shark.swim();
shark.breath();
Animal whale = seaAnimalFactory.getAnimal("WHALE");
whale.swim();
whale.breath();
Animal octopus = seaAnimalFactory.getAnimal("OCTOPUS");
octopus.swim();
octopus.breath();
}
}
Behavioral Design Pattern
Template Pattern
abstract class House {
abstract void buildFoundation();
abstract void buildPillars();
abstract void buildWalls();
abstract void buildWindows();
public final void contructHouse() {
buildFoundation();
buildPillars();
buildWalls();
buildWindows();
}
}
class GlassHouse extends House {
@Override
void buildFoundation() {
}
@Override
void buildPillars() {
}
@Override
void buildWalls() {
}
@Override
void buildWindows() {
}
}
class WoodenHouse extends House {
@Override
void buildFoundation() {
}
@Override
void buildPillars() {
}
@Override
void buildWalls() {
}
@Override
void buildWindows() {
}
}
class TemplatePatternDemo {
public static void main(String[] args) {
House glassHouse = new GlassHouse();
glassHouse.contructHouse();
House woodenHouse = new WoodenHouse();
woodenHouse.contructHouse();
}
}
State Pattern
public interface State {
public void doAction(Context context);
}
public class Context {
private State state;
public Context() {
state = null;
}
public void setState(State state) {
this.state = state;
}
public State getState() {
return state;
}
}
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";
}
}
public class StopState implements State {
public void doAction(Context context) {
System.out.println("Player is in stop state");
context.setState(this);
}
public String toString() {
return "Stop State";
}
}
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());
}
}
Obeserver Pattern
interface Subject {
void registerObserver(Observer observer);
void removeObserver(Observer observer);
void notifyObservers();
}
class Product implements Subject {
private ArrayList<Observer> observers = new ArrayList<Observer>();
private String productName;
String availability;
public Product(String productName, String productType, String availability) {
super();
this.productName = productName;
this.availability = availability;
}
public ArrayList<Observer> getObservers() {
return observers;
}
public void setObservers(ArrayList<Observer> observers) {
this.observers = observers;
}
}
public String getProductName() {
return productName;
}
public void setProductName(String productName) {
this.productName = productName;
}
public String getAvailability() {
return availability;
}
public void setAvailability(String availability) {
this.availability = availability;
notifyObservers();
}
public void notifyObservers() {
System.out.println("Notifying to all the subscribers when product became available");
for (Observer ob : observers) {
ob.update(this.availability);
}
}
public void registerObserver(Observer observer) {
observers.add(observer);
}
public void removeObserver(Observer observer) {
observers.remove(observer);
}
}
interface Observer {
void update(String availability);
}
class Person implements Observer {
String personName;
public Person(String personName) {
this.personName = personName;
}
public String getPersonName() {
return personName;
}
public void setPersonName(String personName) {
this.personName = personName;
}
public void update(String availabiliy) {
System.out.println("Hello " + personName + ",
Product is now " + availabiliy + " on flipkart");
}
}
class ObserverPatternMain {
public static void main(String[] args) {
Person arpitPerson = new Person("Arpit");
Person johnPerson = new Person("John");
Product samsungMobile = new Product("Samsung", "Mobile", "Not available");
samsungMobile.registerObserver(arpitPerson);
samsungMobile.registerObserver(johnPerson);
samsungMobile.setAvailability("Available");
}
}
Facade Pattern
class CPU {
public void freeze() {...}
public void jump(long position) {...}
public void execute() {...}
}
class Memory {
public void load(long position, byte[] data) {...}
}
class HardDrive {
public byte[] read(long lba, int size) {...}
}
class ComputerFacade {
private CPU processor;
private Memory ram;
private HardDrive hd;
public ComputerFacade() {
this.processor = new CPU();
this.ram = new Memory();
this.hd = new HardDrive();
}
public void start() {
processor.freeze();
ram.load(BOOT_ADDRESS, hd.read(BOOT_SECTOR, SECTOR_SIZE));
processor.jump(BOOT_ADDRESS);
processor.execute();
}
}
class You {
public static void main(String[] args) {
ComputerFacade computer = new ComputerFacade();
computer.start();
}
}
Proxy Pattern
Another Example
public interface Image {
void display();
}
public class RealImage implements Image {
private String fileName;
public RealImage(String fileName){
this.fileName = fileName;
loadFromDisk(fileName);
}
@Override
public void display() {
System.out.println("Displaying " + fileName);
}
private void loadFromDisk(String fileName){
System.out.println("Loading " + fileName);
}
}
public class ProxyImage implements Image{
private RealImage realImage;
private String fileName;
public ProxyImage(String fileName){
this.fileName = fileName;
}
@Override
public void display() {
if(realImage == null){
realImage = new RealImage(fileName);
}
realImage.display();
}
}
public class ProxyPatternDemo {
public static void main(String[] args) {
Image image = new ProxyImage("test_10mb.jpg");
image.display();
System.out.println("");
image.display();
}
}
Decorator Pattern
Another Example
interface Car {
public void manufactureCarBody();
}
class BMWCar implements Car {
private String engine;
public String getEngine() {
return engine;
}
public void setEngine(String engine) {
this.engine = engine;
}
@Override
public void manufactureCarBody() {
}
}
abstract class CarDecorator implements Car {
Car car;
public CarDecorator(Car car) {
this.car = car;
}
public void manufactureCarBody() {
car.manufactureCarBody();
}
}
class DieselCarDecorator extends CarDecorator {
public DieselCarDecorator(Car car) {
super(car);
}
public void manufactureCarBody() {
car.manufactureCarBody();
addEngine(car);
}
public void addEngine(Car car) {
if (car instanceof BMWCar) {
BMWCar BMWCar = (BMWCar) car;
BMWCar.setEngine("Diesel Engine");
}
}
}
class PetrolCarDecorator extends CarDecorator {
public PetrolCarDecorator(Car car) {
super(car);
}
public void manufactureCarBody() {
car.manufactureCarBody();
addEngine(car);
}
public void addEngine(Car car) {
if (car instanceof BMWCar) {
BMWCar BMWCar = (BMWCar) car;
BMWCar.setEngine("Petrol Engine");
}
}
}
class DecoratorClient {
public static void main(String[] args) {
Car bmwCar1 = new BMWCar();
DieselCarDecorator carWithDieselEngine = new DieselCarDecorator(bmwCar1);
carWithDieselEngine.manufactureCarBody();
Car bmwCar2 = new BMWCar();
PetrolCarDecorator carWithPetrolEngine = new PetrolCarDecorator(bmwCar2);
carWithPetrolEngine.manufactureCarBody();
}
}
MVC - Architectural Pattern
public class Student {
private String rollNo;
private String name;
public String getRollNo() {
return rollNo;
}
public void setRollNo(String rollNo) {
this.rollNo = rollNo;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
public class StudentView {
public void printStudentDetails(String studentName, String studentRollNo) {
System.out.println("Student: ");
System.out.println("Name: " + studentName);
System.out.println("Roll No: " + studentRollNo);
}
}
public class StudentView {
public void printStudentDetails(String studentName, String studentRollNo) {
System.out.println("Student: ");
System.out.println("Name: " + studentName);
System.out.println("Roll No: " + studentRollNo);
}
}
public class StudentController {
private Student model;
private StudentView view;
public StudentController(Student model, StudentView view) {
this.model = model;
this.view = view;
}
public void setStudentName(String name) {
model.setName(name);
}
public String getStudentName() {
return model.getName();
}
public void setStudentRollNo(String rollNo) {
model.setRollNo(rollNo);
}
public String getStudentRollNo() {
return model.getRollNo();
}
public void updateView() {
view.printStudentDetails(model.getName(), model.getRollNo());
}
}
More patterns are coming soon in this article... your suggestions are welcome. :)