/**
Patterns by Sandeep Desai
http://www.thedesai.net
email: s_desai@hotmail.com
This document is a java program that contains examples of Patterns
Book Reference:
 Head First Design Patterns by Eric Freeman, Elisabeth Freeman
 Design Patterns: Elements of reusable Object Oriented Software
    by Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides
Websites:
 The Portland Patterns Repository http://c2.com/cgi/wiki?WelcomeVisitors
 Hillside Group: http://hillside.net/

A Pattern is a solution to a problem in a context
(Context is a recurring situation)
(Problem is the set of constraints)

Patterns give you general solutions to design problems
Patterns make it easier to handle application changes

An Anti Pattern tells you how to go from a problem to a BAD solution


One way to group patterns
Creational Patterns involve object instantiation and all provide a way to decouple
a client from the objects it needs to instantiate
  e.g Factory Method, Abstract Factory, Singleton, Prototype, Builder
Behavioural Pattern is concerned with how classes and objects interact and
  distribute responsibility
 e.g Strategy, Observer, Template Method, Command, Iterator, State, Visitor,
     Mediator, Interpreter, Chain of Responsibility, Memento
Structural Patterns let you compose classes or objects into larger structures
  e.g Decorator, Proxy, Facade, Composite, Adapter, Flyweight, Bridge

Another grouping is
Class patterns describe how relationships between classes are defined via inheritance
Relationships in class patterns are established at compile time
 e.g Tempalte Method, Factory Method, Adapter, Interpreter
Object Patterns describe relationships between objects and are primarily defined by
composition. Realtionships in object pattersn are typically create at runtime and are
more dynamic and flexible

Pattern Catalog contains list of patterns

Formal Pattern description, define following when creating a new pattern
Pattern name
Intent (Short Description)
Motivation (Detailted description)
Applicability
Structure (Diagram)
Participants (lists the classes used)
Collaborations (how the classes work together)
Consequences (Good and Bad of usage)
Implementation/Sample Code
Known Uses
Related Patterns

OO Principles
 Separation of concerns, do not have class to do many misc things
 Cohesion, degree to which class designed for one purpose
 Encapsulate what varies
 Favor composition over inheritance
 Program to interface not implementation
 Classes should be open for extension but closed for modification
 Depend on abstractions. Do not depend upon concrete classes
 Principle of least knowledge (demeter) Talk only to your immediate friends
    (Loose coupling)
 A class hould have only one reason to change

*/

import java.io.*;

import java.util.*;

import java.lang.reflect.*;

/****************************** Strategy Pattern start ************************
Strategy pattern defins a family of algorithms, encapsulates each one and makes
  them interchangeable.
Strategy lets the algorithm vary independantly from clients that use it
Alternative to inheritance

In example below putting the fly method in a Duck will lead to class explosion
*/
interface

FlyBehavior {
  public void fly();
}

interface QuackBehavior {
  public void quack();
}

abstract class Duck {
  FlyBehavior flyBehavior;
  QuackBehavior quackBehavior;

  public Duck() {
  }

  abstract void display();

  public void setFlyBehavior(FlyBehavior fb) {
    flyBehavior = fb;
  }

  public void setQuackBehavior(QuackBehavior qb) {
    quackBehavior = qb;
  }

  public void performFly() {
    flyBehavior.fly();
  }

  public void performQuack() {
    quackBehavior.quack();
  }
}

class FlyWithWings implements FlyBehavior {
  public void fly() {
    System.out.println("I'm flying!!");
  }
}

class FlyNoWay implements FlyBehavior {
  public void fly() {
    System.out.println("I can't fly");
  }
}

class Quack implements QuackBehavior {
  public void quack() {
    System.out.println("Quack");
  }
}
class Squeak implements QuackBehavior {
  public void quack() {
    System.out.println("Squeak");
  }
}

class MallardDuck extends Duck {
  public MallardDuck() {
    quackBehavior = new Quack();
    flyBehavior = new FlyWithWings();
  }

  public void display() {
    System.out.println("I'm a real Mallard duck");
  }
}

class RubberDuck extends Duck {
  public RubberDuck() {
    flyBehavior = new FlyNoWay();
    quackBehavior = new Squeak();
  }

  public void display() {
    System.out.println("I'm a rubber duckie");
  }
}

class StrategyPattern {
  public static void run() {
    MallardDuck md = new MallardDuck();
    RubberDuck rd = new RubberDuck();
    System.out.println("**** Strategy Pattern *****");
    md.display();
    md.performFly();
    rd.display();
    rd.performFly();
  }
}

/***************************** Strategy Pattern end ************************/

/***************************** Observer Pattern start ************************
 Publisher/Subject
*/
interface Observable {
  public void add(Observable o);

  public void remove(Observable o);
}

interface Observer {
  public void update(Observable o, Object args);
}

class StockData {
  String ticker;
  int price;
}

class Brokerage extends java.util.Observable {
  public void setStockPrice(String ticker, int price) {
    StockData stock = new StockData();
    stock.price = price;
    stock.ticker = ticker;
    setChanged();
    notifyObservers(stock);
  }
}

class Investor implements java.util.Observer {
  public void update(java.util.Observable o, Object args) {
    StockData sd = (StockData)args;
    System.out.println("notified=>" + sd.ticker + "=" + sd.price);
  }
}

class ObserverPattern {
  public static void run() {
    Brokerage b = new Brokerage();
    Investor i = new Investor();
    b.addObserver(i);

    System.out.println("*** Observer pattern ***");
    b.setStockPrice("ORCL", 15);
  }
}

/**************************** Observer pattern end ************************/

/**************************** Decorator pattern start ************************
Decorator - Attach additional responsibilites to an object dynamically
Decoration provides a flexible alternative to subclassing for extending
   functionality
Implement wrappers e.g Java File API in java.io.*

+---InputStream (abstract)
|
+---FileInputStream
+---StringBufferInputStream
+---ByteArrayInputStream
+---FilterInputStream (abstract)
    |
    +---PushBackInputStream (Wrapper)
    +---BufferedInputStream
    +---DataInputStream
    +---LineNumberInputStream
*/
class LowerCaseInputStream extends FilterInputStream {
  public LowerCaseInputStream(InputStream in) {
    super(in);
  }

  public int read() throws IOException {
    int c = super.read();
    return (c == -1 ? c : Character.toLowerCase((char)c));
  }

  public int read(byte[] b, int offset, int len) throws IOException {
    int result = super.read(b, offset, len);
    for (int i = offset; i < offset + result; i++) {
      b[i] = (byte)Character.toLowerCase((char)b[i]);
    }
    return result;
  }
}

class DecoratorPattern {
  public static void run() {
    int c;
    System.out.println("*** Decorator pattern ***");
    try {
      PrintStream ps =
        new PrintStream(new BufferedOutputStream(new FileOutputStream("test.txt")));
      ps.print("HELLO\nWORLD\n");
      ps.close();
      InputStream in =
        new LowerCaseInputStream(new BufferedInputStream(new FileInputStream("test.txt")));

      while ((c = in.read()) >= 0) {
        System.out.print((char)c);
      }

      in.close();
    } catch (IOException e) {
      e.printStackTrace();
    }
  }
}

/**************************** Decorator pattern end ************************/

/**************************** Factory pattern start ************************
The Factory Method Pattern defins an interface for creating an object, but lets
subclass decide which class to instantiate. Factory method lets a class defer
instantiation to subclass
*/
abstract class ProductA {
  public void ship() {
    System.out.println("shipping product");
  }
}
abstract class ProductB {
}
// Replace String type with implementation specific way of creating products
interface Creator {
  ProductA factoryMethod(String type);
}

class ConcreteProductA1 extends ProductA {
}
class ConcreteProductA2 extends ProductA {
}
class ConcreteProductB extends ProductB {
}

class ConcreteCreator implements Creator {
  public ProductA factoryMethod(String type) {
    return new ConcreteProductA1();
  }
}

/**
The Abstract Factory Patterns provides an interface for creating families of related
or dependant objects without specifying their concrete classes
*/
interface

AbstractFactory {
  ProductA createProductA(String type);

  ProductB createProductB(String type);
}

class ConcreteFactory1 {
  ProductA createProductA(String type) {
    if (type.equals("A1"))
      return new ConcreteProductA1();
    if (type.equals("A2"))
      return new ConcreteProductA2();
    return null;
  }

  ProductB createProductB(String type) {
    return new ConcreteProductB();
  }
}

class FactoryPattern {
  public static void run() {
    ConcreteFactory1 factory1 = new ConcreteFactory1();
    ProductA productA = factory1.createProductA("A1");
    System.out.println("*** Factory pattern ***");
    productA.ship();
  }
}

/**************************** Factory pattern end ************************/

/**************************** Singleton pattern start ************************
The Singleton Pattern ensures a class has only one instance, and provides a
global point of access to it
java.lang.Runtime example of Singleton
*/
class Singleton {
  private static Singleton uniqueInstance;

  private Singleton() {
  } // prevents creation by other classes
  // remove synchronized if you do not want thread safe and fast performance

  public static synchronized Singleton getInstance() {
    if (uniqueInstance == null) {
      uniqueInstance = new Singleton();
    }
    return uniqueInstance;
  }
}

class SingletonPattern {
  public static void run() {
    System.out.println("*** Singleton pattern ***");
    Singleton s = Singleton.getInstance();
  }
}

/**************************** Singleton pattern end ************************/

/**************************** Command pattern start ************************
Command - Encapsulate a request as an object, therby letting you parameterize
client with different requests, queue or log request and support undoable operations
e.g usage is Web Server that schedules HTTP requests as a pool of threads
we can also use this to implement a persistent transaction system where we write
commands requests to disk and execute them one by one, when we crash we can
recover from the persistent storage
*/
interface

Command {
  public void execute(); // execute request

  public void undo();
}

class MacroCommand implements Command {
  Command[] commands;

  public MacroCommand(Command[] commands) {
    this.commands = commands;
  }

  public void execute() {
    for (int i = 0; i < commands.length; i++) {
      commands[i].execute();
    }
  }

  public void undo() {
    for (int i = 0; i < commands.length; i++) {
      commands[i].undo();
    }
  }
}

class Light {
  String name;

  public Light(String name) {
    this.name = name;
  }

  public void on() {
    System.out.println(name + " Light is on");
  }

  public void off() {
    System.out.println(name + " Light is off");
  }
}

class LightOffCommand implements Command {
  Light light;

  public LightOffCommand(Light light) {
    this.light = light;
  }

  public void execute() {
    light.off();
  }

  public void undo() {
    light.on();
  }
}

class LightOnCommand implements Command {
  Light light;

  public LightOnCommand(Light light) {
    this.light = light;
  }

  public void execute() {
    light.on();
  }

  public void undo() {
    light.off();
  }
}

class GarageDoor {
  public GarageDoor() {
  }

  public void up() {
    System.out.println("Garage Door is Open");
  }

  public void down() {
    System.out.println("Garage Door is Closed");
  }
}

class GarageDoorOpenCommand implements Command {
  GarageDoor garageDoor;

  public GarageDoorOpenCommand(GarageDoor garageDoor) {
    this.garageDoor = garageDoor;
  }

  public void execute() {
    garageDoor.up();
  }

  public void undo() {
    garageDoor.down();
  }
}

// Client/Invoker
class SimpleRemoteControl {
  Command[] slot = new Command[3];

  public SimpleRemoteControl() {
  }

  public void setCommand(int i, Command command) {
    slot[i] = command;
  }

  public void buttonWasPressed(int i) {
    slot[i].execute();
  }

  public void undo(int i) {
    slot[i].undo();
  }
}

class CommandPattern {
  public static void run() {
    System.out.println("*** Command pattern ***");
    SimpleRemoteControl remote = new SimpleRemoteControl();
    Light kitchenLight = new Light("Kitchen Light");
    Light bedroomLight = new Light("Bedroom Light");
    remote.setCommand(0, new LightOnCommand(kitchenLight));
    remote.setCommand(1, new LightOnCommand(bedroomLight));
    GarageDoor garageDoor = new GarageDoor();
    remote.setCommand(2, new GarageDoorOpenCommand(garageDoor));
    remote.buttonWasPressed(2);
    remote.undo(2);
  }
}

/**************************** Command pattern end ************************/

/**************************** Adapter and Facade pattern start ************************
The Adapter Pattern converts the interface of a class into another interface
the clients expect. Adapter lets classes work together  that couldn't otherwise
because of incompatible interfaces
Class Adapter uses multiple inheritance which is not supported by Java
Decorator Pattern adds behavior, Adapter converts behaviour
Facade Patterns simplifies behaviour
*/
interface

// Object Adapter Pattern
Target {
  public void request();
}
class Adaptee {
  public void specificRequest() {
  }
}

// Adapter can adapt more than one Target
class Adapter implements Target {
  Adaptee a;

  public Adapter(Adaptee a) {
    this.a = a;
  }

  public void request() {
    a.specificRequest(); // convert request to Adaptee request
  }
}

class Client {
  public static void run() {
    Adaptee a = new Adaptee();
    Adapter adapter = new Adapter(a);
    adapter.request(); // We made the Adaptee behave like Target
  }
}

class EnumerationIterator implements Iterator {
  Enumeration enumeration;

  public EnumerationIterator(Enumeration enumeration) {
    this.enumeration = enumeration;
  }

  public boolean hasNext() {
    return enumeration.hasMoreElements();
  }

  public Object next() {
    return enumeration.nextElement();
  }

  public void remove() {
    throw new UnsupportedOperationException();
  }
}

class AdapterPattern {
  public static void run() {
    String[] s = { "hello", "world" };
    Vector v = new Vector(Arrays.asList(s));
    Iterator iterator = new EnumerationIterator(v.elements());
    System.out.println("*** Adapter pattern ***");
    while (iterator.hasNext()) {
      System.out.println(iterator.next());
    }
  }
}

/**
The Facade Pattern povides a unified interface to a set of interfaces in a subsystem
Facade defines a higher-level interface that makes the subsystem easier to use
*/
class A {
}
class B {
}
class C {
}

// Simplify access to A, B, C etc
class Facade {
}

/**************************** Adapter and Facade pattern end ************************/

/**************************** Template Method pattern start ************************
The Template Method Pattern defines the skeleton of an algortihm in a method,
deferring some steps to subclasses. Template Method lets subclases redefine
certain steps of an algorithm without changing the algorithm's structure
e.g java.util.Arrays.binarySearch(Object[] a, Object key, Comparator c)
Strategy allows interchangeable algorithms
Template defines outline of algorithm
*/
abstract class Algorithm {

  public final void templateMethod() {
    step1();
    if (hook())
      step2();
    step3();
  }

  public void step1() {
    System.out.println("Step 1");
  }

  public final void step2() {
    System.out.println("Step 2");
  } // can't override this step

  public abstract void step3();

  public boolean hook() {
    return false;
  } // hook with default implementation
}

class OverrideAlgorithm extends Algorithm {
  public void step1() {
    System.out.println("Step 1 override");
  } // override

  public void step3() {
    System.out.println("Step 3");
  }

  public boolean hook() {
    return true;
  } // hook with default implementation
}

class TemplateMethodPattern {
  public static void run() {
    System.out.println("*** Template Method pattern ***");
    OverrideAlgorithm a = new OverrideAlgorithm();
    a.templateMethod();
  }
}

/**************************** Template Method pattern end ************************

/**************************** Iterator and Composite pattern start ************************
Iterator provides a way to access the elements of an aggregate object sequentially
without exposing its underlying representation
*/
class Item {
  private String name;

  public Item(String name) {
    this.name = name;
  }

  public String getName() {
    return name;
  }
}

class MyCollection {
  Item[] items = new Item[2];

  public void add(int i, String name) {
    items[i] = new Item(name);
  }

  public Iterator iterator() {
    return new MyCollectionIterator(items);
  }
}

class MyCollectionIterator implements Iterator {
  Item[] items;
  int index = 0;

  public MyCollectionIterator(Item[] items) {
    this.items = items;
  }

  public Object next() {
    Item item = items[index++];
    return item;
  }

  public boolean hasNext() {
    if (index >= items.length || items[index] == null)
      return false;
    else
      return true;
  }

  public void remove() {
    throw new UnsupportedOperationException();
  }
}

class IteratorPattern {
  public static void run() {
    System.out.println("*** Iterator pattern ***");
    MyCollection fruits = new MyCollection();
    fruits.add(0, "Apple");
    fruits.add(1, "Orange");
    for (Iterator it = fruits.iterator(); it.hasNext(); ) {
      Item item = (Item)it.next();
      System.out.println(item.getName());
    }
  }
}

/**
Composite - compose objects into tree structures to represent part-whole hierarchies.
Composite lets clients treate individual objects and compositions of objects uniformly
*/
abstract class Component {
  public abstract String getName();

  public abstract void print();

  public void add(Component c) {
    throw new UnsupportedOperationException();
  }

  public void remove(Component c) {
    throw new UnsupportedOperationException();
  }
}

class Leaf extends Component {
  private String name;

  public Leaf(String name) {
    this.name = name;
  }

  public void print() {
    System.out.println("Leaf=>" + name);
  }

  public String getName() {
    return name;
  }
}

class Composite extends Component {
  ArrayList components = new ArrayList();
  private String name;

  public Composite(String name) {
    this.name = name;
  }

  public String getName() {
    return name;
  }

  public void print() { // recursive print
    System.out.println("Composite=>" + name);
    for (Iterator it = components.iterator(); it.hasNext(); ) {
      Component c = (Component)it.next();
      c.print();
    }
  }

  public void operation() {
  }

  public void add(Component c) {
    components.add(c);
  }

  public void remove(Component c) {
    components.remove(c);
  }

  public Component getChild(int i) {
    return (Component)components.get(i);
  }

  public Iterator iterator() {
    return components.iterator();
  }
}

class CompositePattern {
  public static void run() {
    System.out.println("*** Composite pattern ***");
    Composite foodComposite = new Composite("Food");
    Composite fruitComposite = new Composite("Fruits");
    fruitComposite.add(new Leaf("Apple"));
    fruitComposite.add(new Leaf("Orange"));
    foodComposite.add(fruitComposite);
    foodComposite.add(new Leaf("Carrot"));
    foodComposite.print();
  }
}

class IteratorAndCompositePattern {
  public static void run() {
    IteratorPattern.run();
    CompositePattern.run();
  }
}

/**
We can create a Collection Food that contains a Fruit Colleciton and
Vegetable Collection. The class to handle both would be a composite Pattern
*/

/**************************** Iterator and Composite pattern end ************************/

/**************************** State pattern start ************************
The State Pattern allows an object to alter its behavior when its internal state
changes. The object will appear to changes its class
Reduces the if statements required
*/
interface State {
  public void operation1();

  public void operation2();

  public void operation3();

  public void print();
}

class Context {
  State1 state1 = new State1(this);
  State2 state2 = new State2(this);
  State currentState = state1;

  public void setState(State state) {
    currentState = state;
    currentState.print();
  }

  public State getState() {
    return currentState;
  }

  public void operation1() {
    currentState.operation1();
  }

  public void operation2() {
    currentState.operation1();
  }

  public void operation3() {
    currentState.operation1();
  }
}

class State1 implements State {
  Context context;

  State1(Context context) {
    this.context = context;
  }

  public void operation1() {
    context.setState(context.state2);
  }

  public void operation2() {
    context.setState(context.state1);
  }

  public void operation3() {
    context.setState(context.state1);
  }

  public void print() {
    System.out.println("State1");
  }
}

class State2 implements State {
  Context context;

  State2(Context context) {
    this.context = context;
  }

  public void operation1() {
    context.setState(context.state1);
  }

  public void operation2() {
    context.setState(context.state2);
  }

  public void operation3() {
    context.setState(context.state2);
  }

  public void print() {
    System.out.println("State2");
  }
}

class StatePattern {
  public static void run() {
    System.out.println("*** State pattern ***");
    Context stateMachine = new Context();
    stateMachine.operation1();
    stateMachine.operation2();
  }
}

/**************************** State pattern end ************************/

/**************************** Proxy pattern start ************************
Proxy pattern provides a surrogate or placeholder for another object to control
access to it
Remote Proxy as used by RMI and CORBA has client stub and server skeleton
Virutal Proxy for object that maybe expensive to create e.g An Image Loader
     that displays a message while images is being loaded
Firewall Proxy, controls access to a set of network resources, protecting the
     subject from bad clients.
Caching Proxy, provides temporary storage for results of operations that are
     expensive. It can also allow multiple clients to share the results to
     reduce computation or network latency
Synchronization Proxy, provides safe access to a subject from multiple threads
Complexity hiding proxy, aka Facade Proxy
Copy on write proxy, controls the copying of the object by defering the copying
      of an object until it is required by a client. This is a variant
      of the virtual proxy
*/
interface Employee {
  String getName();

  public void add(Employee employee);

  boolean isManager();

  public void print();
}

class EmployeeImpl implements Employee {
  String name;
  ArrayList subs = new ArrayList();
  boolean manager;

  public EmployeeImpl(String name, boolean manager) {
    this.name = name;
    this.manager = manager;
  }

  public String getName() {
    return name;
  }

  public void add(Employee employee) {
    subs.add(employee);
  }

  public boolean isManager() {
    return manager;
  }

  public void print() {
    System.out.println(name + "=" + subs.size());
  }
}

class EmployeeInvocationHandler implements InvocationHandler {
  Employee employee;

  public EmployeeInvocationHandler(Employee employee) {
    this.employee = employee;
  }

  public Object invoke(Object proxy, Method method,
                       Object[] args) throws IllegalAccessException {
    System.out.println(" in Proxy invoke");
    try {
      if (!employee.isManager() && method.getName().equals("add"))
        return null;
      else
        method.invoke(employee, args);
    } catch (InvocationTargetException e) {
      e.printStackTrace();
    }
    return null;
  }
}

class ProxyPattern {
  public static Employee getEmployeeProxy(Employee employee) {
    return (Employee)Proxy.newProxyInstance(employee.getClass().getClassLoader(),
                                            employee.getClass().getInterfaces(),
                                            new EmployeeInvocationHandler(employee));
  }

  public static void run() {
    System.out.println("*** Proxy pattern ***");
    Employee larry = new EmployeeImpl("Larry", true);
    Employee curly = new EmployeeImpl("Curly", false);
    Employee moe = new EmployeeImpl("Moe", false);
    Employee larryProxy = getEmployeeProxy(larry);
    Employee curlyProxy = getEmployeeProxy(curly);
    Employee moeProxy = getEmployeeProxy(moe);
    larryProxy.add(curlyProxy);
    larryProxy.add(moeProxy);
    try {
      curlyProxy.add(moeProxy);
    } catch (Exception e) {
      System.out.println("Only Managers can add employees");
    }
    larryProxy.print();
    curlyProxy.print();
  }
}

/**************************** Proxy pattern end ************************/

/***********************************************************************
A Compound Pattern combines two or more patterns into a solution that solves a
recurring or general problem
Model View Pattern
View uses the Composite patterns as it consistes of nested
   windows/panels/textboxes/buttons
The view is configured with the strategy. The controller provides the strategy
  as the view delegates the control to the controller
The model implementes the Observer pattern as it informs the views when the
  state changes

Bridge Pattern is used to vary not only your implementation but also your
  abstractions e.g different remote controls controlling different TV

The Builder pattern allows you to encapsulate the construction of a product
  and allow it to be constructed in steps (A multi step factory)
  e.g A Vacation Package Planner
  The steps are bookHotel() bookPlane() bookCar()

Chain of responsibility allows more that one object to handle a request
e.g Email filter

Flyweight pattern creates many virtual instances for one instance of a class
  e.g Image Thumbnail viewer where instead of having on object per thumbnail
        to speed up you can have one virtual Thumbnail viewer

Interpreter pattern is used for building an interperter for a language
class Expression { interpret(context) }
class FooCommand extends Expression { interpret(context) }

Mediator Pattern centralizes complex communications and control between related
 objects like a controller in an MVC pattern

Memento Pattern returns an object to one of its previous states e.g for an
   undo request

Prototype Pattern is used when creating an instance of a class is either
 expensive or complicated typically use a lookup service and return a clone

Visitor pattern adds capabilites to a composite of objects when encapsulation
  is not important
*/
public class Patterns {
  public static void main(String[] args) {
    StrategyPattern.run();
    ObserverPattern.run();
    DecoratorPattern.run();
    FactoryPattern.run();
    SingletonPattern.run();
    CommandPattern.run();
    AdapterPattern.run();
    TemplateMethodPattern.run();
    IteratorAndCompositePattern.run();
    StatePattern.run();
    ProxyPattern.run();
  }
}