Design Patterns The Gang of Four suggests a few strategies Outline for Lecture 22 for creating good o-o designs, including … I. Specific design • Design to interfaces. patterns A. Façade • Favor composition over inheritance B. Adapter • Find what varies and encapsulate C. Singleton it D. Iterator E. Factories Façade One of the simplest patterns is Façade. Its purpose is to …

“provide a unified interface to a set of interfaces in a subsystem. Façade defines a higher-level interface that makes the subsystem easier to use.” [GoF, p. 185]

In other words, the purpose of façade is to provide an interface that is simpler to use. We’ve seen an example of this in one of the last two or three lectures. What is it?

Façade

Subsystem classes

Lecture 22 Object-Oriented Languages and Systems 1

Façade

Intent: You want to use an existing system. You need to define your own interface.

Problem: You need to use only a subset of a complex system.

Solution: Present a new interface to the client of the existing system.

Implementation: Define a new class that has the required interface, and have it use the existing system.

Can you think of another example of Façade?

Adapter The is similar to Façade. However, in this case, we have an existing interface that we are trying to design to.

Consider the case where we need to store an ordered collection of String s. We want to do certain things with these String s:

• get the ith string • insert a String in the ith position • return the number of String s in the collection • remove and return the ith String • remove and discard all String s Now, one way to implement this is to create a LinkedList of String s ( LinkedList ).

What’s wrong with that? (What does Skrien say? What is still wrong with it?)

Remember the GoF’s first strategy for creating good o-o design?

Let’s specify what we want our StringList to do:

CSC/ECE 517 Lecture Notes © 2007, Edward F. Gehringer 2

public interface StringList { //get the i-th string public String get(index i);

//remove and return the i-th string public String remove(index i);

//insert s in the i-th position public void insertElementAt(String s, index i);

//remove and discard all strings public void clear();

//return the # of strings in the collection public int size(); }

Where do we find a class to implement the StringList interface? There’s no Java class with exactly this behavior, although LinkedList and ArrayList are close.

An elegant solution is to introduce an adapter class, which delegates all of the functionality to a hidden class such as LinkedList .

Here is an implementation using the old, non-generic, LinkedList :

Lecture 22 Object-Oriented Languages and Systems 3

public class StringListAdapter implements StringList { private LinkedList v = new LinkedList();

//get the i-th string public String get(index i) { return (String) v.get(i); }

//remove and return the i-th string public String remove(index i) { return (String) v.remove(i); }

//insert s in the i-th position public void insertElementAt(String s, index i) { v.insertElementAt(s, i); }

//remove and discard all strings public void clear() { v.clear(); }

//return the number of strings in the list public int size() { return v.size(); } }

If we had had such a class in our program under Java 1.4, we could easily have changed it to use the generic LinkedList in Java 1.5.

Adapter

Intent: Match an existing object to a particular interface.

Problem: A system has the right data and behavior but the wrong interface. Typically used when you have to make something a derivative of an abstract class you already have or are defining.

Solution: The adapter provides a “wrapper” with the desired interface.

CSC/ECE 517 Lecture Notes © 2007, Edward F. Gehringer 4

Implementation: Contain the existing class in another class. Have the containing class match the required interface and call the methods of the contained class.

Adapter and Façade have many similarities. They are both wrappers, but they are different kinds of wrappers. Let’s compare them.

Façade Adapter Are there preexisting classes? Is there an interface we must design to? Does an object need to behave polymorphically? Is a simpler interface needed?

Can you think of another example of Adapter?

Singleton The Singleton pattern is used to ensure that only one object of a particular class is instantiated.

It can be implemented by having either—

• an instance variable that “contains” (references) the desired object, or • a special method that instantiates the desired object. To make sure that objects are not created in any other way (viz., by using the constructor), define the constructor of the class to be protected or private.

For example, suppose we are writing a program that plays bridge.

• When we deal the cards, we start with a card deck that contains 52 cards. • We don’t want to create the deck every time we deal, so we simply create the card deck once at the start of the program and copy it whenever we need it.

Lecture 22 Object-Oriented Languages and Systems 5

Our initial card deck is a singleton.

There are at least three ways to implement a Singleton in Java:

1. Use an instance variable to create the object when the class is loaded:

public class Singleton { public static final Singleton instance = new Singleton(); private Singleton() { } //...any other methods... }

2. Create the instance when the class is loaded, but provide a method to get the instance variable.

public class Singleton { private static final Singleton instance = new Singleton(); private Singleton() { } public static Singleton getInstance() { return instance; } ...any other methods... }

Note that the singleton is used differently than in the first case:

Case 1: Singleton s = Singleton.instance;

Case 2: Singleton s = Singleton.getInstance();

3. Use to create the instance.

• When the getInstance() method is called, it checks to see if the object has already been instantiated. If it has, the method simply returns (a reference to) the object.

CSC/ECE 517 Lecture Notes © 2007, Edward F. Gehringer 6

If it hasn’t, the method instantiates it and returns a reference to the object.

What is the advantage of doing this?

Singleton

Intent: Prevent the instantiation of multiple objects of this class.

Problem: Several different client objects need to refer to the same thing, and you want to ensure that you do not have more than one of them.

Solution: Guarantees one instance.

Implementation: Use a private or protected constructor, and provide a public instance variable or method that creates the object exactly once.

Iterator Remember ’s do: method? It would iterate over any kind of Collection .

Why is this a useful method to have?

Let’s see how the same effect can be achieved in Java.

Since Java 1.1, Java has allowed classes to be nested within other classes. A class defined inside another class is known as an inner class .

Inner classes are useful for at least two reasons: • The name of the inner class is known only within its . Thus, it does not “pollute” the namespace of the package. • The code of an inner class can refer directly to names from enclosing scopes, including both class and instance varia- bles and methods, and local variables of enclosing blocks.

A Fixed Stack

Lecture 22 Object-Oriented Languages and Systems 7

Here is an example adapted from the Java tutorial documentation, a class FixedStack , which implements a stack, and defines an iterator of elements from the stack, from top to base: public class FixedStack { Object array[]; int top = 0; FixedStack(int fixedSizeLimit) { array = new Object[fixedSizeLimit]; }

public void push(Object item) { array[top++] = item; } public boolean isEmpty() { return top == 0; } // other stack methods go here...

/** This adapter class is defined as part of its * target class, It is placed alongside the * variables it needs to access. */ class Iterator implements java.util.Iterator { int count = top; public boolean hasNext() { return count > 0; } public Object next() { if (count == 0) throw new java.util.NoSuchElementException ("FixedStack"); return array[--count]; } public void remove() { … } } public java.util.Iterator elements() { return new Iterator(); } }

The interface java.util.Iterator is used to communicate a series of values to a client.

CSC/ECE 517 Lecture Notes © 2007, Edward F. Gehringer 8

Note that FixedStack does not directly implement the Iterator interface. Why not?

Thus, a separate adapter class is used to return the elements one by one.

Note that the adapter class needs to access the array containing the stack elements.

It can directly refer to instance variables of the stack, since the adapter is defined inside FixedStack .

Iterator

Intent: Allow clients to iterate over the elements of a collection without knowing how the collection is implemented.

Problem: Collections may be implemented in many ways, with different ways of moving from one item to the next. If the implementation of the collection changes, the code for sequencing over it may have to change too.

Solution: Provide a standard interface for starting an iteration, moving to the next element, and determining whether the end of the collection has been reached.

Implementation: Implement each of the above methods for each type of collection; then callers can simply call them to iterate over the collection.

Factories Suppose we have a class X that needs to iterate over some FixedStack s. For example, it may want to take the cross-product of the elements in two FixedStack s to produce a matrix.

In order to do this, X should not create the iterator itself. Why not?

Instead, it should call which method?

Lecture 22 Object-Oriented Languages and Systems 9

Class FixedStack is serving as a “factory” of iterators.

Abstract Factories A frequent application of factories is to provide an interface for creating families of objects in a particular hierarchy without having to specify their type in advance.

Recall the Polygon example from Skrien §3.8 (Lecture 18). There were three different kinds of Polygon s: Square s, Rectangle s, and Triangle s.

When the user clicks in the canvas, a polygon corresponding to the current tool is drawn. How will we do this? What do you think of this code? public void mouseClicked(MouseEvent e) { if(... currentTool specifies a triangle ) ... add a triangle to the canvas here else if(... currentTool specifies a rectangle ) ... add a rectangle to the canvas here else if ... }

Instead, we could design the currentTool to act as a factory that would create a tool of the correct shape.

In order to do this, we need to do two things:

• Make the mouseClicked method call a creation routine for a new polygon. • Make this creation routine clone a new polygon of the correct type.

public void mouseClicked(MouseEvent e) { Polygon p = currentTool.createPolygon(); ... add p to the canvas }

CSC/ECE 517 Lecture Notes © 2007, Edward F. Gehringer 10

public Polygon createPolygon(Point center) { Polygon p = poly.clone(); ... move p to the center point return p; }

In order for this to work, each Tool object needs to maintain a reference to an object of its type (referenced by the poly variable).

Abstract Factory

Intent: To create families or sets of objects for clients.

Problem: Families of related objects need to be instantiated from a single place in the code.

Solution: Coordinate the creation of families of objects. Takes the rules of how to do the instantiation out of the client, and puts it back in the class of the object that is being created.

Implementation: Define an abstract class that specifies which objects are to be made. Then implement one concrete class for each family.

Lecture 22 Object-Oriented Languages and Systems 11