1 more design patterns cs 3331 fall 2009. 2 gof patterns creational structuralbehavioral abstract...
TRANSCRIPT
1
More Design Patterns
CS 3331
Fall 2009
2
GoF Patterns
Creational Structural Behavioral
Abstract Factory Adapter Chain of ResponsibilityBuilder Bridge CommandFactory Method Composite InterpreterPrototype Decorator IteratorSingleton Façade Mediator
Flyweight MementoProxy Observer
StateStrategyTemplate MethodVisitor
E. Gamma, R. Helm, R. Johnson, and J. Vlissides. Design Patterns, Elements of ReusableObject-Oriented Software, Addison-Wesley, 1995.
3
Outline
Factory method Adapter Observer Composite
4
Bouncing Ball Revisited
To bounce different types of balls
BouncingBall
Circle
draw()
Ball
draw()
Rectangle
draw()
1
Q: What design pattern is used?
5
Creating Different Balls
Q: What’s the problem with this kind of code?
public class BouncingBall extends java.applet.Applet { private Ball ball;
private static final String BALL_TYPE = “circle”;
public BouncingBall() { if (“circle”.equals(BALL_TYPE)) { ball = new Circle(); } else if (“rectangle”.equals(BALL_TYPE)) { ball = new Rectangle(); } else { ball = new Circle(); } }
// the rest of code …}
6
A Better Way of Creating Balls
Q: Why is this code better?
public class BouncingBall extends java.applet.Applet { private Ball ball;
public BouncingBall() { ball = createBall(); }
protected Ball createBall() { return new Circle(); }
// the rest of code …}
7
Example (Cont.)
How to bounce a triangle ball?
public class TriangleBouncingBall extends BouncingBall {
protected Ball createBall() { return new Triangle(); }
private static class Triangle implements Ball { public void draw() { /* … */ } // the rest of code here … }}
8
Factory Method
To define an interface for creating an object, but let subclasses to decide which class to instantiate.
Product
ConcreteProduct
AbstractClass
factoryMethod()operation()
ConcreteClass
factoryMethod() return new ConcreteProduct();
p = factoryMethod();
Q: Have we seen a similar design pattern before?
9
ExerciseRefactor the following applet to apply Factory Method.
public class ConfigurableClock extends java.applet.Applet {
private ClockDisplay display;
public ConfigurableClock() { display = new DigitalDisplay(); }
// the rest of code here …}
Also, define a subclass that uses an AnalogDisplay.
10
Outline
Factory method Adapter Observer Composite
11
Bouncing Cars
How to bounce instances of the class Car?
public class BouncingCar extends BouncingBall {
protected Ball createBall() { return new Car(); }}
public class BounceableCar extends Car implements Ball { public void draw() { /* … */ }
// the rest of code here … }}
BounceableCar();
12
Adapter
To convert the interface of a class into another interface that clients expect.
Client Target
operation()
Adaptee
operation()
adaptee.operation();
Adapter
operation()
13
Adapter (Cont.)
Client Target
operation()
Adaptee
operation()
Adapter
14
Exercise
Define an adapter class so that the class Teacher can also work with the client.
Staff
Teacher
+Teacher(n: String)+getName(): String
Student
+Student(n: String)+getName(): String
Client
+doIt(s: Student)
15
Outline
Factory method Adapter Observer Composite
16
A Closer Look at JButton
How the button events (e.g., clicking) are handled?
JButton button = new JButton(“Ok”);button.addActionListener(new OkButtonListener());…
private class OkButtonListener implements ActionListener {
public void actionPerformed(ActionEvent e) { System.out.println(“Ok button pressed!”); }}
17
Static Structure
JButton
addActionListener()removeActionListener()fireActionPerformed()
listeners 0..*
for each l in listeners l.actionPerformed(e);
ActionListener
actionPerformed()
OkButtonListener
actionPerformed()
18
Dynamic Behavior
l : OkButtonListener
addActionListener(l)
fireActionPerformed(e)
actionPerformed(e)
<<create>>
getSource()
e : ActionEvent
button : JButton
19
Observer Pattern
Intent To define relationship between a group of objects such
that whenever one object is updated all others are notified automatically.
Context Multiple objects depend on the state of one object. Set of dependent objects may change at runtime.
Solution Allow dependent objects to register with object of
interest, and notify them of updates when state changes.
20
Structure
attach(Observer)
detach(Observer)
notifyChange()
Subject
update()
Observer
getState()
setState()
ConcreteSubject
update()
ConcreteObserver
public void update() { ... subject.getState() ...}
public void notifyChange() { for each o in observers o.update();}
observers
0..*
subject
ConcreteObserver may depend on ConcreteSubject,but not the other way around!
21
Participants
Subject Knows its observers Provides interface for attaching and detaching observers
Observer Defines an updating interface
ConcreteSubject Stores state of interest Sends notification to observers on state change
ConcreteObserver Maintains a reference to a concrete subject. Stores state that should stay consistent with the subject’s. Implements the updating interface to keep its state consitent
with the subject’s.
22
Collaborationso2 : ConcreteObserver
attach(o1)
attch(o2)setState()
notifyChange()
update()
getState()
update()
getState()
detach(o1)
detach(o2)
o1 : ConcreteObservers : ConcreteSubject
23
Example – Observable Counterspublic class Counter { private int cnt; private List observers = new ArrayList(); public int val() { return cnt; } public void incr() { cnt++; for (Iterator i = observers.iterator(); i.hasNext(); ) { ((CounterObserver) i.next()).valueChanged(); } } public void addObserver(CounterObserver o) { observers.add(o); }}
public interface CounterObserver { void valueChanged();}
24
Example (Cont.)public class CounterApplet extends java.applet.Applet implements CounterObserver {
private Counter counter = new Counter(); private JTextField display = new JTextField(4);
public CounterApplet() { add(display); JButton incr = new JButton(“incr”); incr.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { counter.incr(); } }); add(incr); counter.addObserver(this); }
public void valueChanged() { display.setText(Integer.toString(counter.val())); }}
incr12
25
Exercise
Make the following class observable.
public class Suspect { public void meetWith(Person p) { /* … */ }}
26
Outline
Factory method Adapter Observer Composite
27
Composite Design Pattern To allow clients to treat both single components and collections
of components identically To define recursive data structures such as trees
Clientuses
Leaf
operation()
Component
operation()
Composite
operation()add(Component)remove(Component)
*
28
Example
Composing GUI
public class MyApplet extends java.applet.Applet { public MyApplet() { add(new Label(“My label”)); add(new Button(“My button”)); Panel myPanel = new Panel(); myPanel.add(new Label(“Sublabel”)); myPanel.add(new Button(“Subbutton”)); add(myPanel); }}
Q: How can we add any widgets including panels to applets (i.e., panels)?
29
AWT Components
30
Bouncing Multiple Balls
BouncingBall
Circle
draw()
Ball
draw()
Rectangle
draw()
1
private Ball ball;
public void paint(Graphics g) { // … ball.draw(g); // …}
31
Bouncing Multiple Balls (Cont.)
BouncingBall
Circle
draw()
Ball
draw()
Rectangle
draw()
1..*
private Set balls;
public void paint(Graphics g) { // … for (Iterator i = balls.iterator(); i.hasNext(); ) { ((Ball) i.next()).draw(g); } // …}
32
Using Composite Pattern
BouncingBall Ball
draw(Graphics)
1
Circle
draw(Graphics)
Rectangle
draw(Graphics)
BallGroup
add(Ball)remove(Ball)draw(Graphics)
1..*
33
Using Composite Pattern (Cont.)
public class BallGroup extends Ball {
private Set balls = new HashSet(); // each b in balls is instanceof Ball
public void add(Ball b) { balls.add(b); }
public void remove(Ball b) { balls.remove(b); }
public void paint(Graphics g) { for (Iterator i = balls.iterator(); i.hasNext(); ) { ((Ball) i.next()).draw(g); } }}
34
Exercise
How to represent an expression, E, where E is a number or E + E, e.g., 1, 1 + 2, 3 + 4 + 5, etc?
Number
value()evaluate()
Expression
evaluate()
BinaryExpression
left()right()evaluate()
2
35
Exercise (Cont.)
Write the classes Expression, Number, and BinaryExpression of the previous example.