Title: CENG 217 Object Oriented Design Lecture 5
1CENG 217 Object Oriented Design Lecture 5
Doç. Dr. Halûk Gümüskaya haluk_at_gumuskaya.com /
haluk_at_fatih.edu.trhttp//www.gumuskaya.com
Computing Engineering Department Fatih
University
Thursday, September 24, 2009
2Patterns and GUI Programming
3Lecture Outline
- The ITERATOR as a Pattern
- The Pattern Concept and Introduction to GoF
Design Patterns - The OBSERVER Pattern
- Layout Managers and the STRATEGY Pattern
- Components, Containers, and the COMPOSITE Pattern
- Scroll Bars and the DECORATOR Pattern
- How to Recognize Patterns
- Putting Patterns to Work
4List Iterators
- LinkedListltStringgt list . . .ListIteratorltStr
inggt iterator list.listIterator()while
(iterator.hasNext()) String current
iterator.next() . . . - Why iterators?
-
- Classical List Data Structure
- Traverse links directly
- Link currentLink list.headwhile
(currentLink ! null) Object current
currentLink.data currentLink
currentLink.next - Exposes implementation
- Error-prone
5High-Level View of Data Structures
- Queue
- Array with random access
- List
- ???
6List with Cursor
- for (list.reset() list.hasNext()
list.next()) Object x list.get() .
. . - Disadvantage Only one cursor per list ,
debugging!!! - Iterator is superior concept
7- The ITERATOR as a Pattern
- The Pattern Concept and Introduction to GoF
Design Patterns - The OBSERVER Pattern
- Layout Managers and the STRATEGY Pattern
- Components, Containers, and the COMPOSITE Pattern
- Scroll Bars and the DECORATOR Pattern
- How to Recognize Patterns
- Putting Patterns to Work
8What is a Pattern? History Architectural
Patterns
- Current use comes from the work of the architect
Christopher Alexander. - Alexander studied ways to improve the process of
designing buildings and urban areas. - He formulated over 250 patterns for architectural
designs. C. Alexander et al., A Pattern
Language Towns, Buildings, Construction, Oxford
University Press, 1977. - Patterns can be applied to many different areas
of human endeavor, including software
development - There are patterns of success, and patterns of
failure
9The Pattern Concept Context, Problem and
Solution
- Each pattern is a three-part rule, which
expresses a relation between a certain context, a
problem and a solution. - Hence, the common definition of a pattern A
solution to a problem in a context. - Each pattern has
- a short name
- a brief description of the context
- a lengthy description of the problem
- a prescription for the solution
10Short Passages Pattern
- Context
- "...Long, sterile corridors set the scene for
everything bad about modern architecture..." - Problem
- a lengthy description of the problem, including
- a depressing picture
- issues of light and furniture
- research about patient anxiety in hospitals
- research that suggests that corridors over 50 ft
are considered uncomfortable
11Short Passages Pattern
- Solution
- Keep passages short. Make them as much like rooms
as possible, with carpets or wood on the floor,
furniture, bookshelves, beautiful windows. Make
them generous in shape and always give them
plenty of light the best corridors and passages
of all are those which have windows along an
entire wall.
12Why Patterns?
- Designing object-oriented software is hard and
designing reusable object-oriented software is
even harder. - Erich Gamma - Experienced designers reuse solutions that have
worked in the past. - Well-structured object-oriented systems have
recurring patterns of classes and objects. - Knowledge of the patterns that have worked in the
past allows a designer to be more productive and
the resulting designs to be more flexible and
reusable.
13Benefits of Design Patterns
- Capture expertise and make it accessible to
non-experts in a standard form - Facilitate communication among developers by
providing a common language - Make it easier to reuse successful designs and
avoid alternatives that diminish reusability - Facilitate design modifications
- Improve design documentation
- Improve design understandability
14Drawbacks of Design Patterns
- Patterns do not lead to direct code reuse
- Patterns are deceptively simple
- Teams may suffer from pattern overload
- Patterns are validated by experience and
discussion rather than by automated testing - Integrating patterns into a software development
process is a human-intensive activity
15Software Patterns History
- 1987 - Cunningham and Beck used Alexanders ideas
to develop a small pattern language for Smalltalk - 1990 - The Gang of Four (Gamma, Helm, Johnson and
Vlissides) begin work compiling a catalog of
design patterns - 1991 - Bruce Anderson gives first Patterns
Workshop at OOPSLA - 1993 - Kent Beck and Grady Booch sponsor the
first meeting of what is now known as the
Hillside Group - 1994 - First Pattern Languages of Programs (PLoP)
conference
- 1995 - The Gang of Four (GoF) publish the Design
Patterns book
16GoF (Gang of Four) Design Patterns
- Erich Gamma, Richard Helm, Ralph Johnson, John
Vlissides (Gang of Four GoF), Design
Patterns Elements of Reusable Object-Oriented
Software, Addison Wesley, 1995. - There are 23 design patterns given in this book.
They are classified into 3 purposes
Creational, Structural, and
Behavioral.
17GoF Classification Of Design Patterns
18GoF Essential Elements Of Design Patterns
19GoF Pattern Template
20GoF Pattern Template (Continued)
21GoF Pattern Template (Continued)
22GoF Notation
- The GoF book uses the Object Modeling Technique
(OMT) notation for class and object diagrams
- Notational issues
- Attributes come after the Operations
- Associations are called acquaintances
- Multiplicities are shown as solid circles
- Inheritance shown as triangle
- Dashed line Instantiation Association (Class
can instantiate objects of associated class) (In
UML it denotes a dependency - UML Note is called Dogear box (connected by
dashed line to class operation) Pseudo-code
implementation of operation
23GoF Notation Example
24UML Notation for Design Patterns
- We will use UML in design patterns.
25Creational Patterns (5 patterns)
- Factory Method (OODP Chp10)
- Method in a derived class creates associates
- Abstract Factory
- Factory for building related objects
- Builder
- Factory for building complex objects
incrementally - Prototype
- Factory for cloning new instances from a
prototype - Singleton (OODP Chp10)
- Factory for a singular (sole) instance
26Structural Patterns (7 patterns)
- Adapter (OODP Chp10)
- Translator adapts a server interface for a
client - Bridge
- Abstraction for binding one of many
implementations - Composite (OODP Chp5)
- Structure for building recursive
aggregations - Decorator (OODP Chp5)
- Decorator extends an object transparently
- Facade
- Facade simplifies the interface for a
subsystem - Flyweight
- Many fine-grained objects shared efficiently
- Proxy (OODP Chp10)
- One object approximates another
27Behavioral Patterns (11 patterns)
- Chain of Responsibility
- Request delegated to the responsible service
provider - Command (OODP Chp10)
- Request as first-class object
- Interpreter
- Language interpreter for a small grammar
- Iterator (OODP Chp5)
- Aggregate elements are accessed sequentially
- Mediator
- Mediator coordinates interactions between its
associates - Memento
- Snapshot captures and restores object states
privately
28Behavioral Patterns (continued)
- Observer (OODP Chp5)
- Dependents update automatically when a subject
changes - State
- Object whose behavior depends on its state
- Strategy (OODP Chp5)
- Abstraction for selecting one of many
algorithms - Template Method
- Algorithm with some steps supplied by a
derived class - Visitor (OODP Chp10)
- Operations applied to elements of an
heterogeneous object - structure
29Relationships in GoF Patterns
30An Example Iterator Pattern
- Context
- An aggregate object contains element objects
- Clients need access to the element objects
- The aggregate object should not expose its
internal structure - Multiple clients may want independent access
- Solution
- Define an iterator that fetches one element at a
time - Each iterator object keeps track of the position
of the next element - If there are several aggregate/iterator
variations, it is best if the aggregate and
iterator classes realize common interface types.
Then the client only needs to know the interface
types, not the concrete classes.
31Iterator Pattern
32Iterator Pattern
- Names in pattern are examples
- Names differ in each occurrence of pattern
33- The ITERATOR as a Pattern
- The Pattern Concept and Introduction to GoF
Design Patterns - The OBSERVER Pattern
- Layout Managers and the STRATEGY Pattern
- Components, Containers, and the COMPOSITE Pattern
- Scroll Bars and the DECORATOR Pattern
- How to Recognize Patterns
- Putting Patterns to Work
34Model/View/Controller
- Some programs have multiple editable views
- Example HTML Editor
- WYSIWYG view
- structure view
- source view
- Editing one view updates the other
- Updates seem instantaneous
35HTML Editor MS FrontPage WYSIWYG view
36MS FrontPage Source View
37MS FrontPage Structure (Navigation) View
38Windows
An example of MVC architecture The model is
the filename dp3.ppt. One view is a window
titled CENG 534 Design Patterns, which displays
the contents of a folder containing the file
dp3.ppt. The other view is window called
dp3.ppt Properties, which displays information
related to the file. If the file name is changed,
both views are updated by the controller.
39Model/View/Controller
- Model data structure, no visual representation
- Views visual representations
- Controllers user interaction
- Views/controllers update model
- Model tells views that data has changed
- Views redraw themselves
- MVC is an Architectural Pattern and is not a GoF
Pattern. But it is based on the Observer
(Model/View) GoF pattern.
40Observer Pattern
- Model notifies views when something interesting
happens - Button notifies action listeners when something
interesting happens - Views attach themselves to model in order to be
notified - The View(s) display the Model and is notified
(via a subscribe/notify protocol) whenever the
Model is changed. - Action listeners attach themselves to button in
order to be notified - Generalize Observers attach themselves to
subject - Observer is a behavioral GoF Pattern.
41Observer Pattern
- Context
- An object, called the subject, is source of
events - One or more observer objects want to be notified
when such an event occurs.
- Solution
- Define an observer interface type. All concrete
observers implement it. - The subject maintains a collection of observers.
- The subject supplies methods for attaching and
detaching observers. - Whenever an event occurs, the subject notifies
all observers.
42Observer Pattern
- Java 1.1 introduced a new GUI event model based
on the Observer Pattern - GUI components which can generate GUI events are
called event sources. - Objects that want to be notified of GUI events
are called event (action) listeners. - Event generation is also called firing the event.
- Comparison to the Observer Pattern
- Subject gt event source (Example
JButton)Observer gt Action ListenerConcreteObser
ver gt Action Listener implementation - For an event listener to be notified of an event,
it must first register with the event source.
43Names in Observer Pattern
44Observer Pattern (From GoF Books)
- Intent
- Define a one-to-many dependency between objects
so that when one object changes state, all its
dependents are notified and updated
automatically. - Also Known As
- Dependents, Publish-Subscribe, Model-View.
- Motivation
- The need to maintain consistency between related
objects without making classes tightly coupled.
45Applicability
- Use the Observer pattern in any of the following
situations - When an abstraction has two aspects, one
dependent on the other. Encapsulating these
aspects in separate objects lets you vary and
reuse them independently. - When a change to one object requires changing
others - When an object should be able to notify other
objects without making assumptions about those
objects
46Structure (given in GoF DP Book)
47The Elements of Observer Pattern
- Participants
- Subject
- Keeps track of its observers
- Provides an interface for attaching and detaching
Observer objects - Observer
- Defines an interface for update notification
- ConcreteSubject
- The object being observed
- Stores state of interest to ConcreteObserver
objects - Sends a notification to its observers when its
state changes - ConcreteObserver
- The observing object
- Stores state that should stay consistent with the
subject's - Implements the Observer update interface to keep
its state consistent with the subject's
48Consequences
- Benefits
- Minimal coupling between the Subject and the
Observer - Can reuse subjects without reusing their
observers and vice versa - Observers can be added without modifying the
subject - All subject knows is its list of observers
- Subject does not need to know the concrete class
of an observer, just that each observer
implements the update interface - Subject and observer can belong to different
abstraction layers - Support for event broadcasting
- Subject sends notification to all subscribed
observers - Observers can be added/removed at any time
- Liabilities
- Possible cascading of notifications
- Observers are not necessarily aware of each other
and must be careful about triggering updates - Simple update interface requires observers to
deduce changed item
49Sample Code, Known Uses and Related Patterns
- Sample Code
- We'll see some Java soon!
- Known Uses
- Smalltalk Model/View/Controller user interface
framework - Model Subject
- View Observer
- Controller is whatever object changes the state
of the subject - Related Patterns
- Mediator
- To encapsulate complex update semantics
50Using Design Patterns Templates in Together for
Eclipse Architect 2006
- Use Class By Templete or choose any class on the
diagram and apply one of GoF Design Patterns
51Select Template and Specify Parameters
52Observers and Observables Created by Together
- Create Pattern Links unchecked
53Observers and Observables Created by Together
- Create Pattern Links Checked
54Files Created by Together Subject Vehicle.java
import java.util.ArrayList import
java.util.Iterator / _at_role __Subject
/ public class Vehicle private ArrayList
observers / _at_link
_at_shapeType PatternLink _at_pattern
gof.Observer _at_supplierRole Abstract
Observer / / private TrafficControl
lnkTrafficControl / public void
attach(TrafficControl observer)
observers.add(observer) public void
detach(TrafficControl observer)
observers.remove(observer) public
void notifyObservers() Iterator it
observers.iterator() while
(it.hasNext()) ((TrafficControl)
it.next()).update(this)
55Concrete Subjects Car, Truck, and Van
/ Stores state of interest to
ConcreteObserver objects. Sends a notification
to its observers when its state changes.
/ public class Car extends Vehicle
/ Stores state of interest to
ConcreteObserver objects. Sends a notification
to its observers when its state changes.
/ public class Truck extends Vehicle
/ Stores state of interest to
ConcreteObserver objects. Sends a notification
to its observers when its state changes.
/ public class Van extends Vehicle
56Traffic Control Interface and Concrete Observers
/ _at_role __Observer / public interface
TrafficControl / _at_link
_at_shapeType PatternLink _at_pattern
gof.Observer _at_supplierRole Abstract
Subject / / private Vehicle
lnkVehicle/ void update(Vehicle subject)
/ Implements the Observer updating interface
to keep its state consistent with the
subject's. / public class HighwayPatrol
implements TrafficControl public void
update(Vehicle subject) //put your code
here
/ Implements the Observer updating interface
to keep its state consistent with the
subject's. / public class Sheriff implements
TrafficControl public void update(Vehicle
subject) //put your code here
57Java Implementation of Observer Pattern
- We could implement the Observer pattern from
scratch in Java - But Java provides the Observable/Observer classes
as built-in support for the Observer pattern - The java.util.Observable class is the base
Subject class. Any class that wants to be
observed extends this class. - Provides methods to add/delete observers
- Provides methods to notify all observers
- A subclass only needs to ensure that its
observers are notified in the appropriate
mutators - Uses a Vector for storing the observer references
- The java.util.Observer interface is the Observer
interface. It must be implemented by any observer
class.
58The java.util.Observable Class
- public Observable()
- Construct an Observable with zero Observers
- public synchronized void addObserver(Observer o)
- Adds an observer to the set of observers of this
object - public synchronized void deleteObserver(Observer
o) - Deletes an observer from the set of observers of
this object - protected synchronized void setChanged()
- Indicates that this object has changed
- protected synchronized void clearChanged()
- Indicates that this object has no longer changed,
or that it has already notified all of its
observers of its most recent change. This method
is called automatically by notifyObservers().
59The java.util.Observable Class
- public synchronized boolean hasChanged()
- Tests if this object has changed. Returns true if
setChanged() has been called more recently than
clearChanged() on this object false otherwise. - public void notifyObservers(Object arg)
- If this object has changed, as indicated by the
hasChanged() method, then notify all of its
observers and then call the clearChanged() method
to indicate that this object has no longer
changed. Each observer has its update() method
called with two arguments this observable object
and the arg argument. The arg argument can be
used to indicate which attribute of the
observable object has changed. - public void notifyObservers()
- Same as above, but the arg argument is set to
null. That is, the observer is given no
indication what attribute of the observable
object has changed.
60The java.util.Observer Interface
- public abstract void update(Observable o, Object
arg) - This method is called whenever the observed
object is changed. An application calls an
observable object's notifyObservers method to
have all the object's observers notified of the
change. - Parameters
- o - the observable object
- arg - an argument passed to the
notifyObservers method
61Observable/Observer Example
62ConcreteSubject.java
import java.util.Observable / A subject to
observe! / public class ConcreteSubject extends
Observable private String name private
float price public ConcreteSubject(String
name, float price) this.name name
this.price price System.out.println("Con
creteSubject created " name " at "
price) public String getName() return
name public float getPrice() return
price public void setName(String name)
this.name name setChanged()
notifyObservers(name) public void
setPrice(float price) this.price
price setChanged()
notifyObservers(new Float(price))
63Name and Price Observers
import java.util.Observer import
java.util.Observable // An observer of name
changes. public class NameObserver implements
Observer private String name public
NameObserver() name null
System.out.println("NameObserver created Name is
" name) public void update(Observable
obj, Object arg) if (arg instanceof
String) name (String)arg
System.out.println("NameObserver Name changed to
" name)
import java.util.Observer import
java.util.Observable // An observer of price
changes. public class PriceObserver implements
Observer private float price public
PriceObserver() price 0
System.out.println("PriceObserver created Price
is " price) public void
update(Observable obj, Object arg) if
(arg instanceof Float) price
((Float)arg).floatValue()
System.out.println("PriceObserver Price changed
to " price)
64TestObservers.java
import java.util.Observer import
java.util.Observable // Test program for
ConcreteSubject, NameObserver and
PriceObserver public class TestObservers
public static void main(String args)
// Create the Subject and Observers.
ConcreteSubject s new ConcreteSubject("Corn
Pops", 1.29f) NameObserver nameObs new
NameObserver() PriceObserver priceObs
new PriceObserver() // Add those
Observers! s.addObserver(nameObs)
s.addObserver(priceObs) // Make changes
to the Subject. s.setName("Frosted
Flakes") s.setPrice(4.57f)
s.setPrice(9.22f) s.setName("Surge
Crispies")
65A Simple MVC Example CounterGui
import java.awt.event. import
java.awt. public class CounterGui extends
Frame private int counter 0
// Model! private TextField
tf new TextField(10) // View. public
CounterGui(String title) super(title)
Panel tfPanel new Panel()
tf.setText("0") tfPanel.add(tf)
add("North", tfPanel) Panel buttonPanel
new Panel() Button incButton new
Button("Increment") incButton.addActionListen
er(new ActionListener() public void
actionPerformed(ActionEvent e)
counter tf.setText(counter "")
) buttonPanel.add(incButton)
Button decButton new Button("Decrement")
decButton.addActionListener(new ActionListener()
public void actionPerformed(ActionEvent
e) counter--
tf.setText(counter "") )
buttonPanel.add(decButton)
Button exitButton new Button("Exit")
exitButton.addActionListener(new ActionListener()
public void actionPerformed(ActionEvent
e) System.exit(0) )
buttonPanel.add(exitButton) add("South",
buttonPanel) addWindowListener(new
WindowAdapter() public void
windowClosing(WindowEvent e)
System.exit(0) ) public
static void main(String argv) CounterGui
cg new CounterGui("CounterGui")
cg.setSize(300, 100) cg.setVisible(true)
Where is the controller in this example??
The controllers are the instances of the
anonymous classes which handle the button presses.
66Account System based on MVC Architecture
from Advanced Java 2 Platform, How to Program, H.
M. Deitel)
67The Class Diagrams of the Account System
68Sequence of Events
2.User updates accounts
3. Request account change in model
Controller
1. Views subscribe to event
Model
5. Updated views
4. Notify subscribers
AccountTextView
AccountBarGrapView
AssetPieChartView
69- The ITERATOR as a Pattern
- The Pattern Concept and Introduction to GoF
Design Patterns - The OBSERVER Pattern
- Layout Managers and the STRATEGY Pattern
- Components, Containers, and the COMPOSITE Pattern
- Scroll Bars and the DECORATOR Pattern
- How to Recognize Patterns
- Putting Patterns to Work
70Layout Managers
- User interfaces made up of components
- Components placed in containers
- Container needs to arrange components
- Swing doesn't use hard-coded pixel coordinates
- Advantages
- Can switch "look and feel"
- Can internationalize strings
- Layout manager controls arrangement
71Using Predefined Layout Managers
- There are several built-in layout managers in
Java - FlowLayout left to right, start new row when
full - BoxLayout left to right or top to bottom
- BorderLayout 5 areas, Center, North, South,
East, West - GridLayout grid, all components have same size
- GridBagLayout complex, like HTML table
72Layout Managers
73Layout Managers
- Set layout manager
- JPanel keyPanel new JPanel()
- keyPanel.setLayout(new GridLayout(4, 3))
- Add components
- for (int i 0 i lt 12 i)
- keyPanel.add(buttoni)
74Voice Mail System GUI
- Same backend as text-based system
- Only Telephone class changes
- Buttons for keypad
- Text areas for microphone, speaker
75Voice Mail System GUI
- Arrange keys in panel with GridLayout
- JPanel keyPanel new JPanel()
keyPanel.setLayout(new GridLayout(4, 3)) for
(int i 0 i lt 12 i) JButton keyButton
new JButton(...) keyPanel.add(keyButton)
keyButton.addActionListener(...)
76Voice Mail System GUI
- Panel with BorderLayout for speaker
- JPanel speakerPanel new JPanel()
speakerPanel.setLayout(new BorderLayout())
speakerPanel.add(new JLabel("Speaker"), - BorderLayout.NORTH)
- speakerField new JTextArea(10, 25)
speakerPanel.add(speakerField, BorderLayout.CENTER
)
77Voice Mail System GUI
- Put speaker, keypads, and microphone panel into
content pane - Content pane already has BorderLayout
- Ch5/mailgui/Telephone.java
78Telephone.java (1)
import java.awt. import java.awt.event. import
javax.swing. // Presents a phone GUI for the
voice mail system. public class Telephone //
Constructs a telephone with a speaker, keypad,
and microphone. public Telephone()
JPanel speakerPanel new JPanel()
speakerPanel.setLayout(new BorderLayout())
speakerPanel.add(new JLabel("Speaker"),
BorderLayout.NORTH) speakerField new
JTextArea(10, 25) speakerPanel.add(speakerF
ield, BorderLayout.CENTER) String
keyLabels "1234567890" JPanel keyPanel
new JPanel() keyPanel.setLayout(new
GridLayout(4, 3)) for (int i 0 i lt
keyLabels.length() i) final
String label keyLabels.substring(i, i 1)
JButton keyButton new JButton(label)
keyPanel.add(keyButton)
keyButton.addActionListener(new
ActionListener()
public void actionPerformed(ActionEvent event)
connect.dial(label)
) ..
79Telephone.java (2)
final JTextArea microphoneField new
JTextArea(10,25) JButton speechButton
new JButton("Send speech")
speechButton.addActionListener(new
ActionListener() public
void actionPerformed(ActionEvent event)
connect.record(microphoneField.
getText()) microphoneField.setText
("") ) JButton
hangupButton new JButton("Hangup")
hangupButton.addActionListener(new
ActionListener() public
void actionPerformed(ActionEvent event)
connect.hangup()
) ..
80Telephone.java (3)
JPanel buttonPanel new JPanel()
buttonPanel.add(speechButton)
buttonPanel.add(hangupButton) JPanel
microphonePanel new JPanel()
microphonePanel.setLayout(new BorderLayout())
microphonePanel.add(new JLabel("Microphone"),
BorderLayout.NORTH) microphonePanel.add(mic
rophoneField, BorderLayout.CENTER)
microphonePanel.add(buttonPanel,
BorderLayout.SOUTH) JFrame frame new
JFrame() frame.setDefaultCloseOperation(JFr
ame.EXIT_ON_CLOSE) frame.add(speakerPanel,
BorderLayout.NORTH) frame.add(keyPanel,
BorderLayout.CENTER) frame.add(microphonePa
nel, BorderLayout.SOUTH) frame.pack()
frame.setVisible(true) // Give
instructions to the mail system user. public
void speak(String output)
speakerField.setText(output) public
void run(Connection c) connect c
private JTextArea speakerField private
Connection connect
81Implementing a Custom Layout Manager
- It is not a difficult to write your own layout
manager - Form layout
- Odd-numbered components right aligned
- Even-numbered components left aligned
- Implement LayoutManager interface type
82The LayoutManager Interface Type
- public interface LayoutManager void
layoutContainer(Container parent)
Dimension minimumLayoutSize(Container parent)
Dimension preferredLayoutSize(Container
parent) void addLayoutComponent(String
name, Component comp) void
removeLayoutComponent(Component comp) -
- Ch5/layout/FormLayout.java
- Ch5/layout/FormLayoutTester.java
- Note Can use GridBagLayout to achieve the same
effect
83FormLayout.java (1)
import java.awt. / A layout manager that
lays out components along a central
axis / public class FormLayout implements
LayoutManager public Dimension
preferredLayoutSize(Container parent)
Component components parent.getComponents()
left 0 right 0 height
0 for (int i 0 i lt components.length i
2) Component cleft
componentsi Component cright
componentsi 1 Dimension dleft
cleft.getPreferredSize() Dimension
dright cright.getPreferredSize() left
Math.max(left, dleft.width) right
Math.max(right, dright.width) height
height Math.max(dleft.height, dright.height)
return new Dimension(left GAP
right, height) public Dimension
minimumLayoutSize(Container parent)
return preferredLayoutSize(parent) ..
84FormLayout.java (2)
public void layoutContainer(Container
parent) preferredLayoutSize(parent)
// Sets left, right Component components
parent.getComponents() Insets insets
parent.getInsets() int xcenter
insets.left left int y insets.top
for (int i 0 i lt components.length i
2) Component cleft
componentsi Component cright
componentsi 1 Dimension dleft
cleft.getPreferredSize() Dimension
dright cright.getPreferredSize() int
height Math.max(dleft.height, dright.height)
cleft.setBounds(xcenter - dleft.width, y
(height - dleft.height) / 2, dleft.width,
dleft.height) cright.setBounds(xcenter
GAP, y (height - dright.height) / 2,
dright.width, dright.height) y
height public void
addLayoutComponent(String name, Component comp)
public void removeLayoutComponent(Component
comp) private int left private int
right private int height private static
final int GAP 6
85FormLayoutTester.java
import java.awt. import javax.swing. public
class FormLayoutTester public static void
main(String args) JFrame frame new
JFrame() frame.setLayout(new
FormLayout()) frame.add(new
JLabel("Name")) frame.add(new
JTextField(15)) frame.add(new
JLabel("Address")) frame.add(new
JTextField(20)) frame.add(new
JLabel("City")) frame.add(new
JTextField(10)) frame.add(new
JLabel("State")) frame.add(new
JTextField(2)) frame.add(new
JLabel("ZIP")) frame.add(new
JTextField(5)) frame.setDefaultCloseOperat
ion(JFrame.EXIT_ON_CLOSE) frame.pack()
frame.setVisible(true)
86Strategy Pattern
- Pluggable strategy for layout management
- Layout manager object responsible for executing
concrete strategy - Generalizes to Strategy Design Pattern
- The strategy pattern applies whenever you want to
allow a client to support an algorithm. - It is a behavioral pattern for selecting one of
many algorithms
87Strategy Pattern
- Context
- A class can benefit from different variants for
an algorithm - Clients sometimes want to replace standard
algorithms with custom versions
- Solution
- Define an interface type that is an abstraction
for the algorithm - Actual strategy classes realize this interface
type. - Clients can supply strategy objects
- Whenever the algorithm needs to be executed, the
context class calls the appropriate methods of
the strategy object
88Strategy Pattern Example Layout Management
- The relationships between the names in the
Strategy Pattern and the layout management
manifestation
89Strategy Pattern Example Sorting
- Other manifestation Comparators
- ComparatorltCountrygt comp new
CountryComparatorByName()Collections.sort(countr
ies, comp)
90- The ITERATOR as a Pattern
- The Pattern Concept and Introduction to GoF
Design Patterns - The OBSERVER Pattern
- Layout Managers and the STRATEGY Pattern
- Components, Containers, and the COMPOSITE Pattern
- Scroll Bars and the DECORATOR Pattern
- How to Recognize Patterns
- Putting Patterns to Work
91Containers and Components
- Containers collect GUI components
- Sometimes, want to add a container to another
container - Container should be a component
- Composite design pattern
- Composite method typically invoke component
methods - E.g. Container.getPreferredSize invokes
getPreferredSize of components - It is a structural pattern for building recursive
aggregations
92Composite Pattern
- Context
- Primitive objects can be combined to composite
objects - Clients treat a composite object as a primitive
object
- Solution
- Define an interface type that is an abstraction
for the primitive objects - Composite object collects primitive objects
- Composite and primitive classes implement same
interface type. - When implementing a method from the interface
type, the composite class applies the method to
its primitive objects and combines the results
93Composite Pattern Example in Java
94- The ITERATOR as a Pattern
- The Pattern Concept and Introduction to GoF
Design Patterns - The OBSERVER Pattern
- Layout Managers and the STRATEGY Pattern
- Components, Containers, and the COMPOSITE Pattern
- Scroll Bars and the DECORATOR Pattern
- How to Recognize Patterns
- Putting Patterns to Work
95Scroll Bars
- Scroll bars can be attached to components
- Approach 1 Component class can turn on scroll
bars - Approach 2 Scroll bars can surround component
- JScrollPane pane new JScrollPane(component)
- Swing uses approach 2
- JScrollPane is again a component
- It is a structural pattern for extending an
object transparently
96Decorator Pattern - Context
- Context
- Component objects can be decorated (visually or
behaviorally enhanced) - The decorated object can be used in the same way
as the undecorated object - The component class does not want to take on the
responsibility of the decoration - There may be an open-ended set of possible
decorations
97Decorator Pattern - Solution
- Solution
- Define an interface type that is an abstraction
for the component - Concrete component classes realize this interface
type. - Decorator classes also realize this interface
type. - A decorator object manages the component object
that it decorates - When implementing a method from the component
interface type, the decorator class applies the
method to the decorated component and combines
the result with the effect of the decoration.
98Decorator Pattern Example Scroll Bars
99Decorator Pattern Example Streams
- InputStreamReader reader new
InputStreamReader(System.in) BufferedReader
console new BufferedReader(reader) - BufferedReader takes a Reader and adds buffering
- Result is another Reader Decorator pattern
- Many other decorators in stream library, e.g.
PrintWriter
100- The ITERATOR as a Pattern
- The Pattern Concept and Introduction to GoF
Design Patterns - The OBSERVER Pattern
- Layout Managers and the STRATEGY Pattern
- Components, Containers, and the COMPOSITE Pattern
- Scroll Bars and the DECORATOR Pattern
- How to Recognize Patterns
- Putting Patterns to Work
101How to Recognize Patterns
- Look at the intent of the pattern
- E.g. COMPOSITE has different intent than
DECORATOR - Remember common uses (e.g. STRATEGY for layout
managers) - Not everything that is strategic is an example of
STRATEGY pattern - Use context and solution as "litmus test"
102Litmus Test
- Add border to Swing component
- Border b new EtchedBorder()
- component.setBorder(b)
- Undeniably decorative
- Is it an example of DECORATOR?
103Litmus Test
- Component objects can be decorated (visually or
behaviorally enhanced) PASS - The decorated object can be used in the same way
as the undecorated object PASS - The component class does not want to take on the
responsibility of the decoration FAIL--the
component class has setBorder method - There may be an open-ended set of possible
decorations
104- The ITERATOR as a Pattern
- The Pattern Concept and Introduction to GoF
Design Patterns - The OBSERVER Pattern
- Layout Managers and the STRATEGY Pattern
- Components, Containers, and the COMPOSITE Pattern
- Scroll Bars and the DECORATOR Pattern
- How to Recognize Patterns
- Putting Patterns to Work
105Putting Patterns to Work
- Invoice contains line items
- Line item has description, price
- Interface type LineItem
- Ch5/invoice/LineItem.java
- Product is a concrete class that implements this
interface - Ch5/invoice/Product.java
106LineItem.java and Product.java
/ A line item in an invoice. / public
interface LineItem / Gets the price
of this line item. _at_return the price /
double getPrice() / Gets the
description of this line item. _at_return the
description / String toString()
/ A product with a price and
description. / public class Product implements
LineItem / Constructs a product.
_at_param description the description _at_param
price the price / public Product(String
description, double price)
this.description description this.price
price public double getPrice()
return price public String toString()
return description private String
description private double price
107Bundles
- Bundle set of related items with
descriptionprice - E.g. stereo system with tuner, amplifier, CD
player speakers - A bundle has line items
- A bundle is a line item
- COMPOSITE pattern
- Ch5/invoice/Bundle.java (look at getPrice)
108Bundle.java
import java.util. // A bundle of line items
that is again a line item. public class Bundle
implements LineItem // Constructs a bundle
with no items. public Bundle() items new
ArrayListltLineItemgt() / Adds an
item to the bundle. _at_param item the item to
add / public void add(LineItem item)
items.add(item) public double getPrice()
double price 0 for (LineItem
item items) price item.getPrice()
return price public String
toString() String description
"Bundle " for (int i 0 i lt
items.size() i) if (i gt 0)
description ", " description
items.get(i).toString() return
description private ArrayListltLineItemgt
items
109Discounted Items
- Store may give discount for an item
- Discounted item is again an item
- DECORATOR pattern
- Ch5/invoice/DiscountedItem.java (look at
getPrice) - Alternative design add discount to LineItem
110DiscountedItem.java
/ A decorator for an item that applies a
discount. / public class DiscountedItem
implements LineItem / Constructs a
discounted item. _at_param item the item to be
discounted _at_param discount the discount
percentage / public DiscountedItem(LineItem
item, double discount) this.item
item this.discount discount
public double getPrice() return
item.getPrice() (1 - discount / 100)
public String toString() return
item.toString() " (Discount " discount
")" private LineItem item
private double discount
111Model/View Separation
- GUI has commands to add items to invoice
- GUI displays invoice
- Decouple input from display
- Display wants to know when invoice is modified
- Display doesn't care which command modified
invoice - OBSERVER pattern
112Change Listeners
- Use standard ChangeListener interface type
- public interface ChangeListener
-
- void stateChanged(ChangeEvent event)
-
- Invoice collects ArrayList of change listeners
- When the invoice changes, it notifies all
listeners - ChangeEvent event new ChangeEvent(this)
- for (ChangeListener listener listeners)
- listener.stateChanged(event)
113Change Listeners
- Display adds itself as a change listener to the
invoice - Display updates itself when invoice object
changes state - final Invoice invoice new Invoice()final
JTextArea textArea new JTextArea(20,
40)ChangeListener listener new
ChangeListener() public void
stateChanged(ChangeEvent event) - textArea.setText(...)
114Observing the Invoice
115Iterating Through Invoice Items
- Invoice collect line items
- Clients need to iterate over line items
- Don't want to expose ArrayList
- May change (e.g. if storing invoices in database)
- ITERATOR pattern
116Iterators
- Use standard Iterator interface type
-
- public interface IteratorltLineItemgt
- boolean hasNext()
- LineItem next()
- void remove()
-
- remove is "optional operation" (see ch. 8)
- implement to throw UnsupportedException
- implement hasNext/next manually to show inner
workings - Ch5/invoice/Invoice.java
117Invoice.java (1)
import java.util. import javax.swing.event. /
/ An invoice for a sale, consisting of line
items. public class Invoice // Constructs a
blank invoice. public Invoice()
items new ArrayListltLineItemgt()
listeners new ArrayListltChangeListenergt()
/ Adds an item to the invoice.
_at_param item the item to add / public void
addItem(LineItem item)
items.add(item) // Notify all observers of
the change to the invoice ChangeEvent event
new ChangeEvent(this) for
(ChangeListener listener listeners)
listener.stateChanged(event) /
Adds a change listener to the invoice.
_at_param listener the change listener to add /
public void addChangeListener(ChangeListener
listener) listeners.add(listener)
.
118Invoice.java (2)
/ Gets an iterator that iterates
through the items. _at_return an iterator for
the items / public IteratorltLineItemgt
getItems() return new
IteratorltLineItemgt()
public boolean hasNext() return
current lt items.size() public
LineItem next() return
items.get(current) public void
remove() throw new
UnsupportedOperationException()
private int current 0
public String format(InvoiceFormatter formatter)
String r formatter.formatHeader()
IteratorltLineItemgtiter getItems()
while (iter.hasNext()) r
formatter.formatLineItem(iter.next())
return r formatter.formatFooter()
private ArrayListltLineItemgt items private
ArrayListltChangeListenergt listeners
119Formatting Invoices
- Simple format dump into text area
- May not be good enough,
- E.g. HTML tags for display in browser
- Want to allow for multiple formatting algorithms
- STRATEGY pattern
120InvoiceFormatter.java
/ This interface describes the tasks that an
invoice formatter needs to carry
out. / public interface InvoiceFormatter
/ Formats the header of the invoice.
_at_return the invoice header / String
formatHeader() / Formats a line item
of the invoice. _at_return the formatted line
item / String formatLineItem(LineItem
item) / Formats the footer of the
invoice. _at_return the invoice footer /
String formatFooter()
121SimpleFormatter.java
/ A simple invoice formatter. / public
class SimpleFormatter implements
InvoiceFormatter public String
formatHeader() total 0 return
" I N V O I C E\n\n\n" public
String formatLineItem(LineItem item)
total item.getPrice() return
(String.format( "s
.2f\n",item.toString(),item.getPrice()))
public String formatFooter()
return (String.format("\n\nTOTAL DUE .2f\n",
total)) private double total
122InvoiceTester.java (1)
import java.awt. import java.awt.event. import
javax.swing. import javax.swing.event. // A
program that tests the invoice classes. public
class InvoiceTester public static void
main(String args) final Invoice invoice
new Invoice() final InvoiceFormatter
formatter new SimpleFormatter() // This
text area will contain the formatted invoice
final JTextArea textArea new JTextArea(20,
40) // When the invoice changes, update
the text area ChangeListener listener
new ChangeListener()
public void stateChanged(ChangeEvent event)
textArea.setText(invoice
.format(formatter))
invoice.addChangeListener(listener) //
Add line items to a combo box final
JComboBox combo new JComboBox() Product
hammer new Product("Hammer", 19.95)
Product nails new Product("Assorted nails",
9.95) combo.addItem(hammer) Bundle
bundle new Bundle() bundle.add(hammer)
bundle.add(nails) combo.addItem(new
DiscountedItem(bundle, 10))
123InvoiceTester.java
// Make a button for adding the currently
selected // item to the invoice
JButton addButton new JButton("Add")
addButton.addActionListener(new
ActionListener() public
void actionPerformed(ActionEvent event)
LineItem item (LineItem)
combo.getSelectedItem()
invoice.addItem(item)
) // Put the combo box and the add
button into a panel JPanel panel new
JPanel() panel.add(combo)
panel.add(addButton) // Add the text area
and panel to the content pane JFrame frame
new JFrame() frame.add(new
JScrollPane(textArea),
BorderLayout.CENTER) frame.add(panel,
BorderLayout.SOUTH) frame.setDefaultCloseOp
eration(JFrame.EXIT_ON_CLOSE)
frame.pack() frame.setVisible(true)
124Formatting Invoices
125Formatting Invoices
126References
- This lecture is mainly based on the book Object
Oriented Design and Patterns 1. - There are also some slides adapted from various
resources and my own slides. They are cited
below - Main Resources
- C. Horstmann, Object Oriented Design and Patterns
(OODP), 2nd Edition,, John Wiley, ISBN
0-471-74487-5, 2005. - E. Gamma, R. Helm, R. Johnson, J. Vlissides,
Design Patterns, Elements of Reusable
Object-Oriented Software, Addison-Wesley, 1995. - Lecture notes of CENG 535/410 Design Patterns
course at Fatih University http//www.fatih.edu.t
r/haluk/Teaching/Fatih/200320Fall/ceng20534/cen
g534-2003.htm