Design Patterns CSE 403, Spring 2007, Alverson With material from Marty Stepp 403 lectures. Design patterns A design pattern is a time-tested solution to a common software problem y y Patterns enable a common design vocabulary, improving communication, easing documentation Patterns capture design expertise and allow that expertise to be transferred CSE 403, Spring 2007, Alverson Online Readings Easy reads: y A survey of common design patterns, James Maioriello http://www.developer.com/design/article.php/1502691 y What are design patterns and why do I need them, http://www.developer.com/design/article.php/1474561 Deeper: y Design Patterns: http://c2.com/cgi/wiki?DesignPatterns y C# examples http://www.dofactory.com/Patterns/Patterns.aspx y Java examples http://www.patterndepot.com/put/8/JavaPatterns.htm CSE 403, Spring 2007, Alverson Popular patterns we’ll explore y y y Creational o Singleton o Factory Structural o Decorator o Flyweight Behavioral o Iterator o Strategy CSE 403, Spring 2007, Alverson Pattern: Singleton a class that has only one instance CSE 403, Spring 2007, Alverson Restricting object creation y Problem: Sometimes we will really only ever need one instance of a particular class. o o y Examples: keyboard reader, printer spooler We'd like to make it illegal to have more than one Why we care: o o o Creating lots of objects can take a lot of time Extra objects take up memory It is a maintenance headache to deal with different objects floating around if they are the same CSE 403, Spring 2007, Alverson Singleton pattern y singleton: an object that is the only object of its type o o ensures that a class has at most one instance provides a global access point to that instance o takes responsibility of managing that instance away from the programmer (illegal to construct more instances) o provide accessor method that allows users to see the (one and only) instance o possibly the most known / popular design pattern! (this should tell you something) CSE 403, Spring 2007, Alverson Implementing Singleton y y y make constructor(s) private so that they can not be called from outside declare a single static private instance of the class write a public getInstance() or similar method that allows access to the single instance o possibly protect / synchronize this method to ensure that it will work in a multi-threaded program CSE 403, Spring 2007, Alverson Singleton sequence diagram CSE 403, Spring 2007, Alverson Singleton example y consider a singleton class RandomGenerator that generates random numbers public class RandomGenerator { private static RandomGenerator gen = new RandomGenerator(); public static RandomGenerator getInstance() { return gen; } private RandomGenerator() {} ... } y possible problem with this class? Always creates the instance, even if the class is not used. CSE 403, Spring 2007, Alverson Singleton example 2 y variation: don't create the instance until needed // Generates random numbers public class RandomGenerator { private static RandomGenerator gen = null; public static RandomGenerator getInstance() { if (gen == null) { gen = new RandomGenerator(); } return gen; } ... } y what could go wrong with this version? CSE 403, Spring 2007, Alverson Singleton example 3 y variation: solve concurrency issue by locking // Generates random numbers public class RandomGenerator { private static RandomGenerator gen = null; public static synchronized RandomGenerator getInstance() { if (gen == null) { gen = new RandomGenerator(); } return gen; } ... } y Is anything wrong with this version? CSE 403, Spring 2007, Alverson Singleton example 4 y variation: solve concurrency issue without unnecessary locking // Generates random numbers. public class RandomGenerator { private static RandomGenerator gen = null; public static RandomGenerator getInstance() { if (gen == null) { synchronized (RandomGenerator.class) { // must test again -- can you see why? // sometimes called test-and-test-and-set if (gen == null) { gen = new RandomGenerator(); } } } return gen; } } CSE 403, Spring 2007, Alverson Singleton exercise y Consider your projects. What classes could be a singleton in this system? CSE 403, Spring 2007, Alverson Pattern: Factory (a variation of Factory Method, Abstract Factory) a class or method used to create objects easily CSE 403, Spring 2007, Alverson Problem: Bulky GUI code y GUI code to construct many components quickly becomes redundant (here, with menus): homestarItem = new JMenuItem("Homestar Runner"); homestarItem.addActionListener(this); viewMenu.add(homestarItem); anotherItem = new JMenuItem(“AnotherItem"); anotherItem.addActionListener(this); viewMenu.add(anotherItem); y another example (with buttons): button1 = new JButton(); button1.addActionListener(this); button1.setBorderPainted(false); button2 = new JButton(); button2.addActionListener(this); button2.setBorderPainted(false); CSE 403, Spring 2007, Alverson Factory pattern y factory: a class whose job is to easily create and return instances of other classes o instead of calling a constructor, use a static method in a "factory" class to set up the object o saves lines, complexity to quickly construct / initialize objects o allows you to defer instantiation until a later point CSE 403, Spring 2007, Alverson Factory implementation When implementing a factory of your own: y The factory itself should not be instantiated o y y The factory uses static methods to construct components The factory should offer as simple an interface to client code as possible. o y make constructor private Don't demand lots of arguments; possibly overload factory methods to handle special cases that need more arguments. Factories are often designed for reuse on a later project or for general use throughout your system CSE 403, Spring 2007, Alverson Factory sequence diagram CSE 403, Spring 2007, Alverson Factory example public class ButtonFactory { private ButtonFactory() {} public static JButton createButton( String text, ActionListener listener, Container panel) { JButton button = new JButton(text); button.setMnemonic(text.charAt(0)); button.addActionListener(listener); panel.add(button); return button; } } CSE 403, Spring 2007, Alverson Pattern: Decorator objects that wrap around other objects to add useful features CSE 403, Spring 2007, Alverson Decorator pattern y decorator: an object that modifies behavior of, or adds features to, another object o o o decorator must maintain the common interface of the object it wraps up used so that we can add features to an existing simple object without needing to disrupt the interface that client code expects when using the simple object the object being "decorated" usually does not explicitly know about the decorator How is this different from inheritance? • decoration is dynamic and allows flexibility • decoration can be applied to many different objects CSE 403, Spring 2007, Alverson Decorator example: I/O y y normal InputStream class has only public int read() method to read one letter at a time decorators such as BufferedReader or Scanner add additional functionality to read the stream more easily // InputStreamReader/BufferedReader decorate InputStream InputStream in = new FileInputStream("hardcode.txt"); InputStreamReader isr = new InputStreamReader(in); BufferedReader br = new BufferedReader(isr); // because of decorator streams, we can read an // entire line from the file in one call // (InputStream only provides public int read() ) String wholeLine = br.readLine(); CSE 403, Spring 2007, Alverson Decorator example: GUI y y normal GUI components don't have scroll bars JScrollPane is a container with scroll bars to which you can add any component to make it scrollable // JScrollPane decorates GUI components JTextArea area = new JTextArea(20, 30); JScrollPane scrollPane = new JScrollPane(area); contentPane.add(scrollPane); CSE 403, Spring 2007, Alverson Pattern: Flyweight a class that has only one instance for each unique state CSE 403, Spring 2007, Alverson Problem of redundant objects y problem: redundant objects can bog down system o many objects have same state o example: string/text structures used by document editors example: File objects that represent the same file on disk o new File("mobydick.txt") new File("mobydick.txt") new File("mobydick.txt") ... new File("notes.txt") new File("notes.txt") CSE 403, Spring 2007, Alverson How does this differ from a const? Flyweight pattern y flyweight: an assurance that no more than one instance of a class will have identical state o o achieved by caching identical instances of objects to reduce object construction similar to singleton, but has many instances, one for each unique-state object o useful for cases when there are many instances of a type but many are the same o examples in Java: String, Image / Toolkit, Formatter CSE 403, Spring 2007, Alverson Implementing a Flyweight y flyweighting works best on immutable objects o immutable: cannot be changed once constructed class pseudo-code sketch: public class Flyweighted { o o o static collection (list) of instances private constructor static method to get an instance: } if (we have created this kind of instance before), get it from the collection and return it else, create a new instance, store it in the collection and return it CSE 403, Spring 2007, Alverson Flyweight sequence diagram CSE 403, Spring 2007, Alverson Implementing a Flyweight public class Flyweighted { private static Map instances; private Flyweighted() {} public static synchronized Flyweighted getInstance(Object key) { if (!instances.contains(key)) { Flyweighted fw = new Flyweighted(key); instances.put(key, fw); return fw; } else { return instances.get(key); } } } CSE 403, Spring 2007, Alverson Class before flyweighting y A class to be flyweighted public class Point { private int x, y; public Point(int x, int y) { this.x = x; this.y = y; } public int getX() { return x; } public int getY() { return y; } public String toString() { return "(" + x + ", " + y + ")"; } } CSE 403, Spring 2007, Alverson Class after flyweighting y A class that has been flyweighted! public class Point { private static Map<String, Point> instances = new HashMap<String, Point>(); public static Point getInstance(int x, int y) { String key = x + ", " + y; if (instances.containsKey(key)) { // reuse return instances.get(key); } Point p = new Point(x, y); instances.put(key, p); return p; } } CSE 403, Spring 2007, Alverson Flyweight exercise y Consider your projects. Is there an opportunity to use a flyweight? CSE 403, Spring 2007, Alverson Pattern: Iterator objects that traverse collections CSE 403, Spring 2007, Alverson Iterator pattern y y iterator: an object that provides a standard way to examine all elements of any collection benefits: o o o o supports variations in the traversal of an aggregate simplifies the aggregate’s interface allows more than one traversal to be pending on an aggregate removes need to know about internal structure of collection or different methods to access data from different collections – puts knowledge in the iterator CSE 403, Spring 2007, Alverson Iterators in Java y y all Java collections have a method iterator that returns an iterator for the elements of the collection can be used to look through the elements of any kind of collection (an alternative to for loop) List<Account> list = new ArrayList<Account>(); // ... add some elements ... for (Iterator<Account> itr = list.iterator(); itr.hasNext(); ) { Account a = itr.next(); System.out.println(a); } CSE 403, Spring 2007, Alverson Adding your own Iterators y when implementing your own collections, it can be convenient to use iterators. class List { public: int size() {…} boolean isEmpty() {…} ListElement* get(int index) {…} } What do you need to know to write next()? public class ListIterator { int currentIndex; public: boolean hasNext() {…} ListElement* first() {…} ListElement* next() {…} ListElement* current() {…} CSE 403, Spring 2007, Alverson } Can there be different iteration strategies? Pattern: Strategy objects that hold alternate algorithms to solve a problem CSE 403, Spring 2007, Alverson Strategy pattern y strategy: an algorithm separated from the object that uses it, and encapsulated as its own object o o o y each strategy implements one behavior, one implementation of how to solve the same problem separates algorithm for behavior from object that wants to act allows changing an object's behavior dynamically without extending / changing the object itself examples: o o o file saving/compression layout managers on GUI containers AI algorithms for computer game players CSE 403, Spring 2007, Alverson Strategy example: Card player // Strategy hierarchy parent // (an interface or abstract class) public interface Strategy { public Card getMove(); } // setting a strategy player1.setStrategy(new SmartStrategy()); // using a strategy Card p1move = player1.move(); // uses strategy All strategies must declare (the same) interface common to all supported CSE 403, Spring 2007,algorithms Alverson Selecting a design pattern y y y Consider how design patterns solve design problems o You’ll need to get familiar with them first Consider design patterns of similar purpose to select the one that best fits your situation o Creational o Structural o Behavioral Consider the aspects of your system most likely to change, evolve, be reused Think of an example of where you could apply a pattern to your project. CSE 403, Spring 2007, Alverson
© Copyright 2024