You are on page 1of 27

Design Patterns & Frameworks

Chapter 3 –
Introduction to Design Patterns

Conducted By Andy LAI

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

 1. creational patterns, which deal with the process of


object creation;
 2. structural patterns, which deal primarily with the
static composition and structure of classes and
objects; and
 3. behavioral patterns, which deal primarily with
dynamic interaction among classes and objects.

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

 Flexibility allows components to be


adapted to different contexts. The more
flexible to a component is, the better is the
chance that it may be reused.

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();
 }

 public void stop() {


 animationThread = null;
 }

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;
 }

 final public int getDelay() {


 return delay;
 }
 protected Thread animationThread;
 protected int delay = 100;
 }
9
4. Concrete Animation Applet
 import java.awt.*;
 import java.util.Calendar;

 public class DigitalClock3 extends AnimationApplet {
 public DigitalClock3() {
 setDelay(1000);
 }
 public void paint(Graphics g) {
 Calendar calendar = Calendar.getInstance();
 int hour = calendar.get(Calendar.HOUR_OF_DAY);
 int minute = calendar.get(Calendar.MINUTE);
 int second = calendar.get(Calendar.SECOND);
 g.setFont(font);
 g.setColor(color);
 g.drawString(hour + ":" + minute / 10 + minute % 10 +
 ":" + second / 10 + second % 10, 10, 60);
 }
 protected Font font = new Font("Monospaced", Font.BOLD, 48);
 protected Color color = Color.green;
10
5. A Double-Buffered Generic Animation Applet
 import java.awt.*;

 public abstract class DBAnimationApplet
 extends AnimationApplet {

 final public void update(Graphics g) {
 if (doubleBuffered) {
 paintFrame(offscreen);
 g.drawImage(im, 0, 0, this);
 } else {
 super.update();
 }
 }

 final public void paint(Graphics g) {
 paintFrame(g);
 }

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();
 }

 3. Minimizes the chance of Misuse



 Design Guideline – Minimize the chance of Misuse

 Well-designed classes should minimize their possible misuse by clearly
identifying any violation of the convention of the classes, preferably at compile
time.

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.

 2. When double-buffering is need, the update() method should be overridden to paint


to 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() {}

 abstract protected void paintFrame(Graphics g);

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()

4. Concrete Animation Applet

24
Page for diagrams
Applet AnimationApplet DBAnimationApplet
start() update()
stop() paint()
run() init()
setDelay() initAnimator()
getDelay() paintFrame()

DigitalClock3 BouncingBall2
patint() initAnimator()
paintFrame()

6. Concrete Double-Buffered Animation Applet: Bouncing Ball

25
Page for diagrams

6. Concrete Double-Buffered Animation Applet: Bouncing Ball


26
Que sti on &
Ans wer Ses si on

27

You might also like