What are Design Patterns? Why do we use them? Types of Design Patterns What Patterns is NOT! Introduction SAP 2007 / Page 4 Introduction to Design Patterns What? Template for writing code Patterns use OO Design Principles Concepts like abstraction, inheritance, polymorphism Why? Readability familiarity Maintenance Speed tested, proven development paradigms Communication shared vocabulary Types of Design Patterns Creational Abstract Factory, Factory Method, Singleton, etc Structural Adapter, Decorator, Faade, Proxy, etc Behavioral Iterator, Observer, State, Strategy, etc Design Patterns SAP 2007 / Page 5 What Patterns are NOT Library of Code? Structure for classes to solve certain problems But arent Libraries and Frameworks also Design Patterns? They are specific implementations to which we link our code They use Design Patterns to write their Java Code Is it something to do with s/w architecture? SAP 2007 / Page 6 Software Architecture Design Patterns Component Interaction Class Interaction Includes Design Patterns Far from it Interface == Abstract Class While we study Design Patterns, Abstract Classes and Interface often mean the same thing. SAP 2007 / Page 7 SAP 2007 / Page 8
Singleton Pattern Factory Method & Abstract Factory Creational Patterns Singleton Pattern the simplest pattern Ensures a class has only one instance, and provides a global point of access to it Where to use? Caches Objects that handle registry settings For Logging Device drivers Patterns Component Example of Singleton Pattern Usage: IWDComponentUsage componentUsage = patternAccessPoint.getSingleton(IPatternRtApi.TRANSACTION);
SAP 2007 / Page 9 Singleton Class Diagram Singleton Class static uniqueInstance // other useful Singleton Data static <synchronized> getInstance() // other useful Singleton Method SAP 2007 / Page 10 Improving performance Double Checked Locking Create Unique Instance Eagerly Do nothing! SAP 2007 / Page 11 Create Unique Instance Eagerly Code: public class Singleton { private static Singleton uniqueInstance = new Singleton(); // other useful instance variables here private Singleton() {} public static synchronized Singleton getInstance() { return uniqueInstance; } // other useful methods here } This code is guaranteed to be thread-safe! SAP 2007 / Page 12 Disadvantage Use only if application always uses the Singleton Or use only if the overhead of creation and runtime aspects of the Singleton is not costly Double-Checked Locking Code: // Danger! This implementation of Singleton not guaranteed to work prior to Java 5 public class Singleton { private volatile static Singleton uniqueInstance; private Singleton() {} public static Singleton getInstance() { if (uniqueInstance == null) { synchronized (Singleton.class) { if (uniqueInstance == null) { uniqueInstance = new Singleton(); } } } return uniqueInstance; } } This is thread-safe again! SAP 2007 / Page 13 Disadvantage Not guaranteed to work prior to Java 5 Factory Method Pattern Creates objects without specifying the exact class to create Most popular OO Pattern
SAP 2007 / Page 14 Depend only on abstractions Do not depend on concrete classes Dependency Inversion Principle Compare Two Implementations Dependent Pizza Store Pizza Store public class DependentPizzaStore { public Pizza createPizza(String style, String type) { Pizza pizza = null; if (style.equals("NY")) { if (type.equals("cheese")) { pizza = new NYStyleCheesePizza(); } else if (type.equals("veggie")) { pizza = new NYStyleVeggiePizza(); } else if (type.equals("pepperoni")) { pizza = new NYStylePepperoniPizza(); } } else if (style.equals("Chicago")) { if (type.equals("cheese")) { pizza = new ChicagoStyleCheesePizza(); } else if (type.equals("veggie")) { pizza = new ChicagoStyleVeggiePizza(); } else if (type.equals("pepperoni")) { pizza = new ChicagoStylePepperoniPizza(); } } else { System.out.println("Error: invalid type of pizza"); return null; } pizza.prepare(); pizza.bake(); pizza.cut(); pizza.box(); return pizza; } } public abstract class PizzaStore { abstract Pizza createPizza(String item); public Pizza orderPizza(String type) { Pizza pizza = createPizza(type); System.out.println("--- Making a " + pizza.getName() + " ---"); pizza.prepare(); pizza.bake(); pizza.cut(); pizza.box(); return pizza; } }
public class NYPizzaStore extends PizzaStore { Pizza createPizza(String item) { if (item.equals("cheese")) { return new NYStyleCheesePizza(); } else if (item.equals("veggie")) { return new NYStyleVeggiePizza(); } else if (item.equals("clam")) { return new NYStyleClamPizza(); } else if (item.equals("pepperoni")) { return new NYStylePepperoniPizza(); } else return null; } }
SAP 2007 / Page 15 Compare Dependencies Dependent Pizza Store Pizza Store SAP 2007 / Page 16 PizzaStore NYStyle CheesePizza ChicagoStyle CheezePizza NYStyle VeggiePizza NYStyle PeppoPizza ChicagoStyle VeggiePizza ChicagoStyle PeppoPizza Pizza NYStyle CheesePizza ChicagoStyle CheezePizza NYStyle VeggiePizza NYStyle PeppoPizza ChicagoStyle VeggiePizza ChicagoStyle PeppoPizza PizzaStore Explanations Not using Factory Method Using Factory Method Dependent Pizza Store depends on all the available Pizzas. Pizza Store depends only on Abstract Pizza which is implemented by specific Pizzas Abstraction Principle violated Depends only on Abstraction Direction of dependency is downward to the different types of Pizzas Different types of pizzas implement Pizza inversion of dependency Addition of a new style of pizzas will require BIG change in code Add new California Style Store and the respective Californian Pizzas extending the Pizza class Code needs to be open for modification Code can be closed for modification, open for extension SAP 2007 / Page 17 Class Diagram of Factory Method SAP 2007 / Page 18 Creator factoryMethod() operations() Concrete Creator factoryMethod() Product Concrete Product Contains methods to manipulate products, since the steps and procedures are generic Creation of product is abstracted Creator Implements concrete product creation Each Concrete Creator knows its respective concrete product Concrete Creator Implements abstract Product Contains specific implementations for the abstract methods/step declared in the Product Interface Concrete Products Abstract Factory Pattern Groups object factories that have a common theme Groups together a set of related products Uses Composition and Inheritance Uses Factory Method to create products Essentially FACTORY SAP 2007 / Page 19 Families Ingredients / Pizzas Ingredients Pizza NY Style: Sauce: Marinara Dough: Thin Crust Cheese: Reggiano Veggies: Garlic, Onion, Mushroom Chicago Style: Sauce: Tomato Dough: Thick Crust Cheese: Mozzarella Veggies: Onion, Mushroom, Capsicum California Style: Sauce: Dough: Cheese: Veggies:...
Cheese Pizza
Veggie Pizza
Pepperoni Pizza SAP 2007 / Page 20 Factory Method versus Abstract Factory Factory Method Abstract Factory SAP 2007 / Page 21 Pizza NYStyle CheesePizza ChicagoStyle CheezePizza NYStyle VeggiePizza NYStyle PeppoPizza ChicagoStyle VeggiePizza ChicagoStyle PeppoPizza PizzaStore Pizza CheesePizza VeggiePizza PeppoPizza PizzaStore Pizza Ingredients NYStyle ChicagoStyle Quick Reference: Different Types of Creational Patterns Name Description Abstract factory Provide an interface for creating families of related or dependent objects without specifying their concrete classes. Factory method Define an interface for creating an object, but let subclasses decide which class to instantiate. Factory Method lets a class defer instantiation to subclasses. Builder Separate the construction of a complex object from its representation so that the same construction process can create different representations. Lazy initialization Tactic of delaying the creation of an object, the calculation of a value, or some other expensive process until the first time it is needed. Object Pool Avoid expensive acquisition and release of resources by recycling objects that are no longer in use Prototype Specify the kinds of objects to create using a prototypical instance, and create new objects by copying this prototype. Singleton Ensure a class only has one instance, and provide a global point of access to it. SAP 2007 / Page 22 SAP 2007 / Page 23
Adapter Pattern Decorator Pattern Faade Pattern Structural Patterns Adapter Pattern Adapter lets classes work together that couldn't otherwise because of incompatible interfaces SAP 2007 / Page 24 Your Existing System Adapter
Vendor Class Client Target Interface request() Adapter request() Adapted specificRequest() Ducks Target Interface public interface Duck { public void quack(); public void fly(); } An implementation the Target Interface public class MallardDuck implements Duck { public void quack() { System.out.println("Quack"); } public void fly() { System.out.println("I'm flying"); } } SAP 2007 / Page 25 Turkeys To-Be-Adapted Interface public interface Turkey { public void gobble(); public void fly(); } An implementation of To-Be-Adapted Interface public class WildTurkey implements Turkey { public void gobble() { System.out.println("Gobble gobble"); } public void fly() { System.out.println("I'm flying a short distance"); } } SAP 2007 / Page 26 Turkey Adapted public class TurkeyAdapter implements Duck { Turkey turkey; public TurkeyAdapter(Turkey turkey) { this.turkey = turkey; } public void quack() { turkey.gobble(); } public void fly() { for(int i=0; i < 5; i++) { turkey.fly(); } } }
SAP 2007 / Page 27 Client Application Test Drive public class DuckTestDrive { public static void main(String[] args) { MallardDuck duck = new MallardDuck(); WildTurkey turkey = new WildTurkey(); Duck turkeyAdapter = new TurkeyAdapter(turkey); System.out.println("The Turkey says..."); turkey.gobble(); turkey.fly(); System.out.println("\nThe Duck says..."); testDuck(duck); System.out.println("\nThe TurkeyAdapter says..."); testDuck(turkeyAdapter); }
static void testDuck(Duck duck) { duck.quack(); duck.fly(); } } SAP 2007 / Page 28 Adapting Enumerations to Iterators public 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(); } } SAP 2007 / Page 29 Decorator Pattern Attach additional responsibilities to an object dynamically. Decorators provide a flexible alternative to sub-classing for extending functionality. Decorators have the same super-type as the objects they decorate You can use more than one decorators to wrap an object
SAP 2007 / Page 30 Concrete Component we can dynamically add new behavior Each component can be used on its own, or wrapped by a decorator Concrete Decorator has an instance variable for the thing it decorates Classes should be open for extension Should be closed for modification Open-Close Principle java.io uses decorator to extend behaviors SAP 2007 / Page 31 FilterInputStream.java public class FilterInputStream extends InputStream { protected volatile InputStream in; protected FilterInputStream(InputStream in) { this.in = in; } public int read() throws IOException { return in.read(); } public int read(byte b[], int off, int len) throws IOException { return in.read(b, off, len); } public long skip(long n) throws IOException { return in.skip(n); } } SAP 2007 / Page 32 Extending java.io New Class LowerCaseInputStream.java public 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; } } SAP 2007 / Page 33 LowerCaseInputStream.java Test Drive public class InputTest { public static void main(String[] args) throws IOException { int c; try { InputStream in = new LowerCaseInputStream( new BufferedInputStream( new FileInputStream("test.txt")));
in.close(); } catch (IOException e) { e.printStackTrace(); } } } SAP 2007 / Page 34 Set up the FileInputStream and decorate it, first with a BufferedInputStream and then with our brand new LowerCaseInputStream filter Remember! Inheritance is one form of extension, but there are other ways to do the same Designs should allow behavior to be extended without the need to modify existing code Decorator Pattern involves a set of decorator classes that are used to wrap concrete classes You can wrap a component with any number of decorators We use inheritance to achieve the type matching, but we arent using inheritance to get behavior Decorators can result in many small objects in our design, and overuse can be complex SAP 2007 / Page 35 Decorator and Adapter Decorator Adapter Both wrap concrete implementations of some type Decorator wraps to add functionality/responsibility Adapter alters the interface it converts one interface to another SAP 2007 / Page 36 Faade Pattern Facade defines a higher-level interface that makes the sub-system easier to use Do not create design that have a large number of classes coupled together so that changes in one part of the system cascade to other parts When you build a lot of dependencies between many classes, you are building a fragile system that will be costly to maintain and complex for others to understand Patterns Team understands Faade better than many people Threading in Java is also another example of Faade Pattern
SAP 2007 / Page 37 Talk only to your immediate friends Principle of Least Knowledge Class Diagram for Faade Pattern SAP 2007 / Page 38 SAP 2007 / Page 39
Command Pattern Observer Pattern Behavioral Patterns Command Pattern Encapsulate a request as an object, thereby letting you parameterize clients with different requests, queue or log requests, and support undo operations. A command class is a convenient place to collect code and data related to a command. A command object can hold information about the command, such as its name or which user launched it; and answer questions about it, such as how long it will likely take. The command is a useful abstraction for building generic components The Command Pattern decouples an object, making a request from the one that knows how to perform it Smart Command objects implement the request themselves rather than delegating it to a receiver SAP 2007 / Page 40 Home Automation through Command Pattern Light.java public class Light { public Light() { }
public void on() { System.out.println("Light is on"); } public void off() { System.out.println("Light is off"); } }
SAP 2007 / Page 41 Command.java public interface Command { public void execute(); public void undo(); } SAP 2007 / Page 42 LightOnCommand.java public class LightOnCommand implements Command { Light light;
public LightOnCommand(Light light) { this.light = light; }
public void execute() { light.on(); }
public void undo() { light.off(); } } SAP 2007 / Page 43 LightOffCommand.java public class LightOffCommand implements Command { Light light;
public LightOffCommand(Light light) { this.light = light; }
public void execute() { light.off(); }
public void undo() { light.on(); } } SAP 2007 / Page 44 Test Drive Command Pattern RemoteLoader.java public class RemoteLoader {
public static void main(String[] args) { RemoteControlWithUndo remoteControl = new RemoteControlWithUndo();
Light livingRoomLight = new Light("Living Room");
LightOnCommand livingRoomLightOn = new LightOnCommand(livingRoomLight); LightOffCommand livingRoomLightOff = new LightOffCommand(livingRoomLight); livingRoomLightOn.execute() ; livingRoomLightOff.execute(); } } SAP 2007 / Page 45 Test Drive Faade and Command Pattern Together You need to look at the code now. SAP 2007 / Page 46 Class Diagram for Command Pattern SAP 2007 / Page 47 Observer Pattern Define a one-to-many dependency between objects so that when one object changes state, all its dependents are notified and updated automatically.
SAP 2007 / Page 48 Subject Interface Isubject.java public interface ISubject { public void registerObserver( IObserver o ) ; public void removeObserver( IObserver o ) ; public void notifyObservers() ; } SAP 2007 / Page 49 Observer Interface IObserver.java public interface IObserver { public void notify( int temp , int humidity , int pressure ) ; } SAP 2007 / Page 50 Design Principle Strive for loosely coupled designs between objects that interact Loose Coupling SAP 2007 / Page 51 The Subject doesnt care, it will deliver notifications to any object that implements the Observer Interface
Loosely coupled designs allow us to build flexible OO Systems that can handle change because they minimize the interdependency between objects
Pull is considered more Correct than Push
Swing makes heavy use of the Observer Pattern
Observer Pattern defines a one-to-many relationship between objects SAP 2007 / Page 52 Thank you! References Head First Design Patterns Eric & Elizabeth Freeman with Kathy Sierra & Bert Bates Wikipedia http://en.wikipedia.org/wiki/Design_pattern_%28computer_science%29 YouTube http://www.youtube.com/codingkriggs SAP 2007 / Page 53