Design Patterns: Horstmann Chapter 5 (Sections 1-7)
Design Patterns: Horstmann Chapter 5 (Sections 1-7)
Unit 5
Spring 2017
can be used.
Jill Seaman
✦A set of consequences that describes the trade-offs and alternatives to
be considered with respect to the design goals being addressed.
1 2
• The following terms are often used to denote the classes that • Delegation: A special form of aggregation, commonly used in
collaborate in a design pattern:
design patterns.
✦The pattern interface is the part of the pattern that is visible to the client ✦A implements its operations/methods by calling methods on B.
class (might be an interface or abstract class).
(Methods may have different names)
✦The implementor class provides low level behavior of the pattern. Often ✦Makes explicit the dependencies between A and B.
the pattern contains many of these.
• Advantages of delegation:
3 4
Encapsulating Traversals with
The ITERATOR Pattern Compare to C++ linked list traversal
• Recall using an Iterator to iterate through the elements of a linked • Recall performing a traversal of a linked list in C++:
list in Java:
• The hasNext method tests whether the iterator is at the end of the • And it’s error-prone: “it is very easy to mess up links and corrupt
list.
the link structure of a linked list”
• The next method returns the current element and advances the
iterator to the next position.
• Why does the Java library use an iterator to traverse a linked list?
5 6
• For a Linked List, we want to be able to add and remove elements • Here is how to traverse the list:
from the middle of the list, but it would be very inefficient to specify list.reset();
a position in a linked list with an integer index. while (list.hasNext()) {
//do something with list.getCurrent();
list.next();
}
7 8
Problem with the Cursor-based Linked List The Iterator as a Design Pattern
• There is only one cursor, you can’t implement algorithms that Name: Iterator Design Pattern
compare different list elements.
Problem Description: Provide a way to access the elements of an aggregate
object sequentially without exposing its underlying representation, for multiple
• You can’t even print the contents of the list for debugging clients simultaneously.
purposes, because it moves the cursor to the end.
Solution: ConcreteIterator class implements the Iterator interface for
accessing and traversing elements. The ConcreteAggregate implements the
Aggregate interface for creating an Iterator object.
• In Java, a List<T> can have any number of iterators attached to it.
9 10
• pack: sets the size of the frame to the smallest size needed to
display its components.
frame.setLayout(new FlowLayout());
frame.add(helloButton);
• Let’s build this:
frame.add(goodbyeButton);
frame.add(textField);
frame.pack();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
13 14
15 16
Example: IconAdapterTester Adapter Pattern: IconAdapter
import java.awt.*;
import javax.swing.*; • Note we use inheritance instead of implementing an interface.
/**
This program demonstrates how an icon is adapted to
a component. The component is added to a frame.
*/
public class IconAdapterTester
{
public static void main(String[] args)
{
Icon icon = new MarsIcon(300);
JComponent component = new IconAdapter(icon);
JFrame frame = new JFrame();
frame.add(component, BorderLayout.CENTER);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
}
17 18
• Client and Adaptee work together without any modification to Name: Strategy Design Pattern
Problem Description: Define a family of algorithms, encapsulate each one, and
either.
Client
• Question: Where does the Adapter Pattern use inheritance?
Where does it use delegation?
Policy
19 20
Example: switching between network protocols Strategy Pattern example: Network protocols
// Context Object: Network Connection
• Based on location (available network connections), switch between public class NetworkConnection {
different types of network connections
private String destination;
private NetworkInterface intf;
✦LocationManager configures NetworkConnection with a concrete private StringBuffer queue;
NetworkInterface based on the current location
public NetworkConnect(String destination, NetworkInterface intf) {
this.destination = destination; this.intf = intf;
✦Application uses the NetworkConnection independently of concrete this.intf.open(destination);
NetworkInterfaces (NetworkConnection uses delegation).
}
public void send(byte msg[]) {
Application queue.concat(msg);
NetworkConnection NetworkInterface
if (intf.isReady()) {
intf.send(queue);
send() open()
receive() close() queue.setLength(0);
setNetworkInterface() send()
LocationManager receive() }
}
public byte[] receive () {
return intf.receive();
Ethernet WaveLAN UMTS
}
WaveLAN = WiFi open() open() open() public void setNetworkInterface(NetworkInterface newIntf) {
UMTS = 3G mobile close()
send()
close()
send()
close()
send() intf.close()
phone network receive() receive() receive()
newIntf.open(destination);
intf = newIntf;
21 22
} }
Strategy Pattern example: Network protocols Strategy Pattern example: Layout Managers
//Abstract Strategy,
//Implemented by EthernetNetwork, WaveLanNetwork, and UMTSNetwork (not shown) • Graphical user interfaces are made up of components (ie JButton)
interface NetworkInterface {
void open(String destination); • Components are placed in containers (like JFrame)
void close();
byte[] receive();
void send(StringBuffer queue);
• Containers need to arrange the components on the screen
bool isReady();
} • Some interface toolkits use hard-coded pixel x-y coordinates
NetworkInterface networkIntf;
if (isEthernetAvailable()) ✦ Can easily switch "look and feel” (MS windows vs Mac)
25 26
• The java.util.Observer interface is the Observer interface. It must be - boolean hasChanged() (see below)
This method is called whenever the observed object is changed. - public void notifyObservers(Object arg)
33 34
Example: Making Buttons Work with UI Actions. Example: Making Buttons Work with UI Actions.
• Recall the JFrame window we made earlier:
• ActionListeners attach themselves to a button, and when the button
is clicked the code of the actionPerformed method is executed.
helloButton.addActionListener(new
• Listener objects implement the following Interface:
ActionListener() {
public void actionPerformed(ActionEvent event) {
textField.setText("Hello, World!");
public interface ActionListener {
}
int actionPerformed(ActionEvent event);
});
}
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack(); ✦Does not use the Java Observer/Observable classes.
frame.setVisible(true);
} ✦The JButton has no state that the observer cares about.
}
37 38
39 40
Example: A hierarchy of user interface objects Example: A hierarchy of user interface objects
• Anatomy of a preference dialog. Aggregates, called Panels, are • An object diagram (it contains instances, not classes) of the
used for grouping user interface objects that need to be resized and previous example:
moved together.
prefs:Window
Top panel
top:Panel main:Panel buttons:Panel
c2:Checkbox cancel:Button
c3:Checkbox
Button panel
c4:Checkbox
41 42
Example: A hierarchy of user interface objects Composite Pattern example: File system
• A class diagram, for user interface widgets
43 44
Composite Pattern example: File system Composite Pattern example: File system
public class CompositeDemo {
// Directory implements the common interface, a composite
public static StringBuffer g_indent = new StringBuffer();
class Directory implements AbstractFile {
private String m_name;
public static void main(String[] args) {
private ArrayList<AbstractFile> m_files = new ArrayList<AbstractFile>();
Directory one = new Directory("dir111"),
public Directory(String name) {
two = new Directory("dir222"),
m_name = name;
thr = new Directory("dir333");
}
File a = new File("a"), b = new File("b"),
public void add(AbstractFile obj) {
c = new File("c"), d = new File("d"), e = new File("e");
m_files.add(obj);
one.add(a);
}
one.add(two);
public void ls() {
one.add(b);
System.out.println(CompositeDemo.g_indent + m_name);
two.add(c); Output: dir111
CompositeDemo.g_indent.append(“ “); // add 3 spaces a
two.add(d);
for (int i = 0; i < m_files.size(); ++i) { dir222
two.add(thr);
AbstractFile obj = m_files.get(i);
thr.add(e); c
obj.ls();
one.ls(); d
}
}
//remove the 3 spaces:
}
dir333
CompositeDemo.g_indent.setLength(CompositeDemo.g_indent.length() - 3); e
}
b
}
45 46
47 48
Example: Adding scrollbars to a UI Component Decorator Pattern: Scroll Bars
• When a component contains more information than can be shown
• The JScrollPane is an instance of the DECORATOR Pattern.
• This code adds scroll bars to a text area (a text area is a box where
you can enter multiple lines of text):
• The JScrollPane is itself a Component.
JTextArea area = new JTextArea(20, 40); // 20 rows, 40 columns ✦It has the same methods as JTextArea, implemented by calling the method
JScrollPane scroller = new JScrollPane(area);
on JTextArea and modifying the result.
frame.add(scroller, BorderLayout.CENTER);
✦It can be decorated by another JScrollPane
JScrollPane(Component view)
Creates a JScrollPane that displays the contents of the specified component, where both
horizontal and vertical scrollbars appear whenever the component's contents are larger
than the view.
49 50
53 54
Composite
“Must allow for hierarchies of variable depth and width”
Iterator
“Must support multiple traversals at same time”
“Must comply with existing interface”
Adapter
“Must reuse existing legacy component”
“Must be notified of changes” Observer
“Must allow functionality to be added during runtime”
Decorator
“Client programs must be able to add functionality”
“Policy and mechanisms should be decoupled”