Professional Documents
Culture Documents
Chapter 3 –
Introduction to Design Patterns
1
1. Topics
Design Patterns
Designing Generic Components
Double-Buffered Generic Animation
Applet
Concrete Classes for Generic Components
Question and Answer Session
2
2. Design Patterns
Among the most importance recent
developments of object-oriented technologies is
the emergence of design patterns and
frameworks, which are intended to address
reuses of design and architectures.
3
The researchers compiled 23 of the most commonly used
general purpose design patterns that are application
domain independent and classified them as
4
3. Designing Generic Components
Generic components are also known as
reusable components.
Two basic techniques of designing generic
components are factorization and
generalization..
5
3.1 Factorization
One way to discover possible generic
components is by identifying recurring
code segments that are identical or nearly
identical. An example of such recurring
code segments are the nearly identical
methods start(), stop(), and run() that
appear in every animation applet.
6
Design Guideline – Maximize Flexibility
7
3.2 Factorization by Inheritance - A Generic
Animation Applet
import java.awt.*;
public class AnimationApplet
extends java.applet.Applet
implements java.lang.Runnable {
public void start() {
animationThread = new Thread(this);
animationThread.start();
}
8
public void run() {
while (Thread.currentThread() == animationThread) {
try {
Thread.currentThread().sleep(delay);
} catch (InterruptedException e) {}
repaint();
}
}
final public void setDelay(int delay) {
this.delay = delay;
}
11
final public void init() {
d = getSize();
im = createImage(d.width, d.height);
offscreen = im.getGraphics();
initAnimator();
}
protected void initAnimator() {}
abstract protected void paintFrame(Graphics g);
protected DBAnimationApplet(boolean doubleBuffered) {
this.doubleBuffered = doubleBuffered;
}
12
protected DBAnimationApplet() {
this.doubleBuffered = true;
}
protected boolean doubleBuffered;
protected Dimension d;
protected Image im;
protected Graphics offscreen;
}
13
5.1 Accommodate various sizes of the view area
1. In order to initializes the off-screen image buffer, we need to know the
dimensions of the viewing area.
Add init() method:
public void init() {
d = getSize();
im = createImage(d.width, d.height);
offscreen = im.getGraphics();
}
14
2. subclass of DBAnimationApplet to get parameters
Overriding init() method:
public void init() {
String param = getParameter(..)
super.init();
}
15
final public void init() {
d = getSize();
im = createImage(d.width, d.height);
offscreen = im.getGraphics();
initAnimator();
}
protected void initAnimator() {}
The init() method is made final, so that it cannot be accidentally overridden by
the subclasses. This approach ensures that initializations of dim, im and
offscreen will always be done properly.
A null implementation is provided for initAnimator(). A subclass needs to
override this protected method only when there are subclass specific
initializations.
protected void initAnimator() {
String param = getParameter(..);
}
16
5.2 Allow the subclasses to decide whether to use
double-buffering.
final public void update(Graphics g) {
if (doubleBuffered) {
paintFrame(offscreen);
g.drawImage(im, 0, 0, this);
} else {
super.update();
}
}
1. When double-buffering is not needed, the default implementation of update()
should be used and the paint() method should be overridden by the subclass to paint a
frame.
17
5.3 Factorize common code segments that
contains variable parts
The third key issue involves the user of double-buffering. The part of the update()
method that deals with double-buffering is common to all animation applets, whereas
the part that deals with painting the frames varies from applet to applet.
final public void update(Graphics g) {
if (doubleBuffered) {
paintFrame(offscreen);
g.drawImage(im, 0, 0, this);
} else {
super.update();
}
}
18
final public void paint(Graphics g) {
paintFrame(g);
}
final public void init() {
d = getSize();
im = createImage(d.width, d.height);
offscreen = im.getGraphics();
initAnimator();
}
protected void initAnimator() {}
19
The initAnimator() and paintFrame() methods are protected, as they are intended only
for the subclasses to override. Abstract method is declared to serve as a placeholder for
the context specific code. The update() and paint(), and init() methods are final so that
the subclasses cannot alter their implementation.
The conventions for using the double-buffered generic animation applet class are as
follows.
• A concrete animation applet should extend the DBAnimationApplet class. The
Boolean parameter of the constructor indicator whether double-buffering is needed.
• Each concrete animation applet must override the paintFrame() method to paint
frames of the animation.
The initAnimator() method may be overridden to provide subclass specific
initializations.
20
6 Concrete Double-Buffered Animation Applet:
BouncingBall 2
<!--BouncineBall2.html-->
<HTML>
<HEAD>
<TITLE> The <B>New</B> BouncingBall Applet </TITLE>
</HEAD>
<BODY BGCOLOR=blue TEXT=white LINK=white VLINK=white>
<HR>
<CENTER>
<H1> The <B>New</B> BouncingBall Applet</H1>
<P>
<APPLET CODE=BouncingBall2.class
WIDTH=250 HEIGHT=150>
</APPLET>
</CENTER>
<HR>
<H2>The Source Code</H2>
<LI><A HREF="BouncingBall2.java">Get the BouncingBall Applet!</A><BR>
<LI><A HREF="DBAnimationApplet.java">Get the DBAnimationApplet!</A><BR>
<HR>
</BODY>
</HTML>
21
import java.awt.*;
public class BouncingBall2 extends DBAnimationApplet {
public BouncingBall2() {
super(true); // double buffering
}
protected void initAnimator() {
String att = getParameter("delay");
if (att != null)
setDelay(Integer.parseInt(att));
x = d.width * 2 / 3 ;
y = d.height - radius;
}
protected void paintFrame(Graphics g) {
g.setColor(Color.white);
g.fillRect(0,0,d.width,d.height);
if (x < radius || x > d.width - radius) {
dx = -dx;
}
22
if (y < radius || y > d.height - radius) {
dy = -dy;
}
x += dx; y += dy;
g.setColor(color);
g.fillOval(x - radius, y - radius, radius * 2, radius * 2);
}
protected int x, y;
protected int dx = -2, dy = -4;
protected int radius = 20;
protected Color color = Color.green;
}
23
Page for diagrams
Applet AnimationApplet
start()
stop()
run()
setDelay()
getDelay()
DigitalClock3
patint()
24
Page for diagrams
Applet AnimationApplet DBAnimationApplet
start() update()
stop() paint()
run() init()
setDelay() initAnimator()
getDelay() paintFrame()
DigitalClock3 BouncingBall2
patint() initAnimator()
paintFrame()
25
Page for diagrams
27