## Object-Oriented Design & Patterns

#### Cay S. Horstmann

### Chapter 10

### More Design Patterns

## Chapter Topics

- The ADAPTER Pattern
- Actions and the COMMAND Pattern
- The FACTORY METHOD Pattern
- The PROXY Pattern
- The SINGLETON Pattern
- The VISITOR Pattern
- Other Design Patterns

## Adapters

- Cable adapter: adapts plug to foreign wall outlet
- OO Programming; Want to adapt class to foreign interface type
- Example: Add `CarIcon` to container
- Problem: Containers take components, not icons
- Solution: Create an adapter that adapts `Icon` to `Component`
- Ch10/adapter/IconAdapter.java
- Ch10/adapter/IconAdapterTester.java

## The ADAPTER Pattern

### Context

1. You want to use an existing class (adaptee) without modifying it.
2. The context in which you want to use the class requires target interface that is different from that of the adaptee.
3. The target interface and the adaptee interface are conceptually related.

## The ADAPTER Pattern

### Solution

1. Define an adapter class that implements the target interface.
2. The adapter class holds a reference to the adaptee. It translates target methods to adaptee methods.
3. The client wraps the adaptee into an adapter class object.

## The ADAPTER Pattern

Name in Design Pattern | Actual Name (Icon->Component)
Adaptee | Icon
Target | JComponent
Adapter | IconAdapter
Client | The class that wants to add icons into a container
targetMethod() | paintComponent(), getPreferredSize()
adapteeMethod() | paintIcon(), getIconWidth(), getIconHeight()

## The ADAPTER Pattern

- In stream library
- Input streams read bytes
- Readers read characters
- Non-ASCII encoding: multiple bytes per char
- System.in is a stream
- What if you want to read characters?
- Adapt stream to reader
- `InputStreamReader`

## The ADAPTER Pattern

Name in Design Pattern | Actual Name (Stream->Reader)
Adaptee | InputStream
Target | Reader
Adapter | InputStreamReader
Client | The class that wants to read text from an input stream
targetMethod() | read (reading a character)
adapteeMethod() | read (reading a byte)

## User Interface Actions

- Multiple routes to the same action
- Example: Cut a block of text
  - Select Edit->Cut from menu
  - Click toolbar button
  - Hit Ctrl+X
- Action can be disabled (if nothing is selected)
- Action has state
- Action should be an object

## User Interface Actions

## The `Action` Interface Type

- Extends `ActionListener`
- Can be enabled/disabled
- Additional state, including
  - Action name
  - Icon
- helloAction.putValue(Action.NAME, "Hello");
- `menu.add(helloAction);`
- Extend `AbstractAction` convenience class

## The `Action` Interface Type

## Action Example

- Ch10/command/CommandTester.java
- Ch10/command/GreetingAction.java

## The COMMAND Pattern

### Context

1. You want to implement commands that behave like objects
   - because you need to store additional information with commands
   - because you want to collect commands.

## The COMMAND Pattern

### Solution

1. Define a command interface type with a method to execute the command.
2. Supply methods in the command interface type to manipulate the state of command objects.
3. Each concrete command class implements the command interface type.
4. To invoke the command, call the execute method.

## The COMMAND Pattern

Name in Design Pattern | Actual Name (Swing actions)
Command | `Action`
ConcreteCommand | subclass of `AbstractAction`
execute() | `actionPerformed()`
state | `name` and `icon`

## Factory Methods

- Every collection can produce an iterator
  `Iterator iter = list.iterator()`
- Why not use constructors?
  `Iterator iter = new LinkedListIterator(list);`
- Drawback: not generic
  `Collection coll = ...;`
  `Iterator iter = new ???(coll);`
- Factory method works for all collections
  `Iterator iter = coll.iterator();`
- Polymorphism!

## The FACTORY METHOD Pattern

### Context

1. A type (the creator) creates objects of another type (the product).
2. Subclasses of the creator type need to create different kinds of product objects.
3. Clients do not need to know the exact type of product objects.

## The FACTORY METHOD Pattern

### Solution

1. Define a creator type that expresses the commonality of all creators.
2. Define a product type that expresses the commonality of all products.
3. Define a method, called the factory method, in the creator type.
   The factory method yields a product object.
4. Each concrete creator class implements the factory method so that it returns an object of a concrete product class.

## The FACTORY METHOD Pattern

Name in Design Pattern | Actual Name (iterator)
Creator | Collection
ConcreteCreator | A subclass of `Collection`
factoryMethod() | iterator()
Product | Iterator
ConcreteProduct | A subclass of `Iterator` (which is often anonymous)

## Not a FACTORY METHOD

- Not all "factory-like" methods are instances of this pattern
- Create `DateFormat` instances
  `DateFormat formatter = DateFormat.getDateInstance();`
  `Date now = new Date();`
  `String formattedDate = formatter.format(now);`
- `getDateInstance` is a static method
- No polymorphic creation

## Proxies

- Proxy: a person who is authorized to act on another person s behalf
- Example: Delay instantiation of object
- Expensive to load image
- Not necessary to load image that user doesn't look at
- Proxy defers loading until user clicks on tab

## Deferred Image Loading

- Normally, programmer uses image for label:
  `JLabel label = new JLabel(new ImageIcon(imageName));`
- Use proxy instead:
  `JLabel label = new JLabel(new ImageProxy(imageName));`
- `paintIcon` loads image if not previously loaded
  `public void paintIcon(Component c, Graphics g, int x, int y)`
  `{`
  `if (image == null) image = new ImageIcon(name);`
  `image.paintIcon(c, g, x, y);`
  `}`

## Proxies

- Ch10/proxy/ImageProxy.java
- Ch10/proxy/ProxyTester.java
- "Every problem in computer science can be solved by an additional level of indirection"
- Another use for proxies: remote method invocation

## The PROXY Pattern

### Context

1. A class (the real subject) provides a service that is specified by an interface type (the subject type)
2. There is a need to modify the service in order to make it more versatile.
3. Neither the client nor the real subject should be affected by the modification.

## The PROXY Pattern

### Solution

1. Define a proxy class that implements the subject interface type.
   The proxy holds a reference to the real subject, or otherwise knows how to locate it.
2. The client uses a proxy object.
3. Each proxy method invokes the same method on the real subject and provides the necessary modifications.

## The PROXY Pattern

Name in Design Pattern | Actual Name (image proxy)
Subject | Icon
RealSubject | ImageIcon
Proxy | ImageProxy
request() | The methods of the `Icon` interface type
Client | JLabel

## Singletons

- "Random" number generator generates predictable stream of numbers
- Example: seed = (seed * 25214903917 + 11) % 248
- Convenient for debugging: can reproduce number sequence
- Only if all clients use the same random number generator
- Singleton class = class with one instance

## Random Number Generator Singleton

`public class SingleRandom`
`{`
`private SingleRandom() { generator = new Random(); }`
`public void setSeed(int seed) { generator.setSeed(seed); }`
`public int nextInt() { return generator.nextInt(); }`
`public static SingleRandom getInstance() { return instance; }`
`private Random generator;`
`private static SingleRandom instance = new SingleRandom();`
`}`

## The SINGLETON Pattern

### Context

1. All clients need to access a single shared instance of a class.
2. You want to ensure that no additional instances can be created accidentally.

## The SINGLETON Pattern

### Solution

1. Define a class with a private constructor.
2. The class constructs a single instance of itself.
3. Supply a static method that returns a reference to the single instance.

## Not a SINGLETON

- Toolkit used for determining screen size, other window system parameters
- `Toolkit` class returns default toolkit
  `Toolkit kit = Toolkit.getDefaultToolkit();`
- Not a singleton--can get other instances of `Toolkit`
- ``Math`` class not example of singleton pattern
- No objects of class `Math` are created

## Inflexible Hierarchies

- How can one add operations to compound hierarchies?
- Example: AWT `Component,` `Container,` etc. form hierarchy
- Lots of operations: `getPreferredSize`,`repaint`
- Can't add new methods without modifying `Component` class
- VISITOR pattern solves this problem
- Each class must support one method
  `void accept(Visitor v)`

## Inflexible Hierarchies

## Visitors

- `Visitor` is an interface type
- Supply a separate class for each new operation
- Most basic form of `accept` method:
  `public void accept(Visitor v) { v.visit(this); }`
- Programmer must implement `visit`

## Visitors

- Problem: Operation may be different for different element types
- Can't rely on polymorphism
- Polymorphism assumes fixed set of methods, defined in superclass
- Trick: Can use variable set of methods if set of classes is fixed
- Supply separate visitor methods:
  `public interface Visitor`
  `{`
  `void visitElementType1(ElementType1 element);`
  `void visitElementType2(ElementType2 element);`
  `...`
  `void visitElementTypen(ElementTypen element);`
  `}`

## Visitors

- Example: Directory tree
- Two kinds of elements: `DirectoryNode`,`FileNode`
- Two methods in visitor interface type:
  `void visitDirectoryNode(DirectoryNode node)`
  `void visitFileNode(FileNode node)`

## Double Dispatch

- Each element type provides methods:
  `public class ElementTypei`
  `{`
  `public void accept(Visitor v) { v.visitElementTypei(this); }`
  `...`
  `}`
- Completely mechanical
- Example:
  `public class DirectoryNode`
  `{`
  `public void accept(Visitor v) { v.visitDirectoryNode(this); }`
  `...`
  `}`

## Visitor Example

- Standard `File` class denotes both files and directories
- Improved design: `FileNode`,`DirectoryNode`
- Common interface type: `FileSystemNode`
- Accepts `FileSystemVisitor`
- Visitor methods:
  `visitFileNode`
  `visitDirectoryNode`

## Visitor Example

- Actual visitor: `PrintVisitor`
- Prints names of files (in `visitFileNode`)
- Lists contents of directories (in `visitDirectoryNode`)
- Maintains indentation level
  `..`
  `command`
  `CommandTester.java`
  `GreetingAction.java`
  `visitor`
  `FileNode.java`
  `DirectoryNode.java`

## Visitor Example

- ch10/visitor/FileSystemNode.java
- ch10/visitor/FileNode.java
- ch10/visitor/DirectoryNode.java
- ch10/visitor/FileSystemVisitor.java
- ch10/visitor/PrintVisitor.java
- ch10/visitor/VisitorTester.java

## Double Dispatch Example

- `DirectoryNode node = new DirectoryNode(new File(".."));
  node.accept(new PrintVisitor());
  `
- `node` is a `DirectoryNode`
- Polymorphism: ``node.accept`` calls `DirectoryNode.accept`
- That method calls `v.visitDirectoryNode`
- `v` is a `PrintVisitor`
- Polymorphism: calls `PrintVisitor.visitDirectoryNode`
- Two polymorphic calls determine
- - node type
  - visitor type

## Double Dispatch Example

## The VISITOR Pattern

### Context

1. An object structure contains element classes of multiple types, and you want to carry out operations that depend on the object types.
2. The set of operations should be extensible over time.
3. The set of element classes is fixed.

## The VISITOR Pattern

### Solution

1. Define a visitor interface type that has methods for visiting elements of each of the given types.
2. Each element class defines an accept method that invokes the matching element visitation method on the visitor parameter.
3. To implement an operation, define a class that implements the visitor interface type and supplies the operation s action for each element type.

## The VISITOR Pattern

Name in Design Pattern | Actual Name (file system visitor)
Element | FileSystemNode
ConcreteElement | FileNode, DirectoryNode
Visitor | FileSystemVisitor
ConcreteVisitor | `PrintVisitor`

## Other Design Patterns

- Abstract Factory
- Bridge
- Builder
- Chain of Responsibility
- Flyweight
- Interpreter
- Mediator
- Memento
- State

## Conclusion: What You Learned

1. Object-oriented design
   The design methodology
   CRC cards and UML diagrams
   Design patterns
2. Advanced Java
   Interface types, polymorphism, and inheritance
   Inner classes
   Reflection
   Multithreading
   Collections
3. User interface programming
   Building Swing applications
   Event handling
   Graphics programming