39
Object Oriented Programming Lecture 5: Refactoring by Inheritance and Delegation - A simple Design Pattern for animation applets, A Generic Function Plotter www.hh.se/staff/jebe/oop2006/main.html

Object Oriented Programming Lecture 5: Refactoring by Inheritance and Delegation - A simple Design Pattern for animation applets, A Generic Function Plotter

Embed Size (px)

Citation preview

Page 1: Object Oriented Programming Lecture 5: Refactoring by Inheritance and Delegation - A simple Design Pattern for animation applets, A Generic Function Plotter

Object Oriented Programming

Lecture 5:Refactoring by Inheritance and Delegation - A simple Design Pattern for animation applets, A Generic Function Plotterwww.hh.se/staff/jebe/oop2006/main.html

Page 2: Object Oriented Programming Lecture 5: Refactoring by Inheritance and Delegation - A simple Design Pattern for animation applets, A Generic Function Plotter

Setting the environment variables for JDK in UNIX

set the CLASSPATH environment variable in your ”.cshrc.private” file

If the CLASSPATH is not set: setenv CLASSPATH ~/test/myclasses

If the CLASSPATH already is set: setenv CLASSPATH

~/test/myclasses::~/classdir/test2::etc

Page 3: Object Oriented Programming Lecture 5: Refactoring by Inheritance and Delegation - A simple Design Pattern for animation applets, A Generic Function Plotter

The Applets Design Pattern

Java applets embedded in web pages Applets are downloaded from a web

server and executed on the client in a web browser or appletviewer

Applets must extend the Applet class Can be found in java.applet package

Page 4: Object Oriented Programming Lecture 5: Refactoring by Inheritance and Delegation - A simple Design Pattern for animation applets, A Generic Function Plotter

Embedding the applets in HTML The simplest form of applet HTML tags:<applet code = byte-code filename

width in pixels

height in pixels>

</applet> Will make the browser execute the applet

in the webpage context

Page 5: Object Oriented Programming Lecture 5: Refactoring by Inheritance and Delegation - A simple Design Pattern for animation applets, A Generic Function Plotter

Interaction between the context and applet

An applet interacts with the context according to a contractual interface

Init() – initialize the applet when it is initially loaded

Start() – activates the applet and is invoked when entering the webpage

Stop() – deactivates the applet Destroy() - destroys the applet when

the webpage is discarded

Page 6: Object Oriented Programming Lecture 5: Refactoring by Inheritance and Delegation - A simple Design Pattern for animation applets, A Generic Function Plotter

Simple animation applet

The applet displays the current time HH:MM:SS

In order draw on the screen we must overload the paint() method

Requires a Thread to control the Animation

Problem: We can’t extend both Applet and Thread...?

Page 7: Object Oriented Programming Lecture 5: Refactoring by Inheritance and Delegation - A simple Design Pattern for animation applets, A Generic Function Plotter

The Runnable Interface The Solution: Java provides the Runnable

Interface Implemented by a class that should run in a

Thread By implemententing Runnable

A class can pass itself as argument to the Thread() constructor

We need to define the run() method that is invoked when starting the Thread

Page 8: Object Oriented Programming Lecture 5: Refactoring by Inheritance and Delegation - A simple Design Pattern for animation applets, A Generic Function Plotter

The start() method

public void start(){if(clockThread != null){

clockThread = new Thread(this);clockThread.start();

}}

Public void stop()clockThread = null;

Calls run()!

Kill the Thread!

Page 9: Object Oriented Programming Lecture 5: Refactoring by Inheritance and Delegation - A simple Design Pattern for animation applets, A Generic Function Plotter

Controlling the Animation -the run() method

public void run(){while(Thread.currentThread() == clockThread){

repaint();try{Thread.currentThread().sleep(1000);}catch(InterruptedException e){};

}}

Calls paint() to draw the time on the screen

Sleep 1 second before redrawing!

Page 10: Object Oriented Programming Lecture 5: Refactoring by Inheritance and Delegation - A simple Design Pattern for animation applets, A Generic Function Plotter

Drawing the time on screen- the paint() method

Public void paint(graphics g){

...

g.setFont(font);

g.setColor(color);

g.drawString(hour + ”:” + minute + ”:” + second);

}

Page 11: Object Oriented Programming Lecture 5: Refactoring by Inheritance and Delegation - A simple Design Pattern for animation applets, A Generic Function Plotter

Idiom: Animation Applet An Idiom: ”How we can program a generic

template that can be reused for a recurring problem” It should be possible to customize and adapt

Applets can produce some graphical output that changes without interaction from the user (animation)

Using the Animation Applet Idiom: extend AnimationApplet and redefine the paint

method

Page 12: Object Oriented Programming Lecture 5: Refactoring by Inheritance and Delegation - A simple Design Pattern for animation applets, A Generic Function Plotter

Double buffering

If painting directly on the screen, the screen will ”flicker”

Double buffering can be used to solve this problem

Double buffering 1 ”draw invisibly” in a background buffer 2 Then update the screen with the buffer

Page 13: Object Oriented Programming Lecture 5: Refactoring by Inheritance and Delegation - A simple Design Pattern for animation applets, A Generic Function Plotter

Double buffering When calling repaint() it will

automatically call the update() update() will clear the screen using

the background color and call the paint method paint(Graphics g);

Solution: To avoid the the ”flicker” - override the update method

Instead of clearing - let update(); paint the buffered image

Page 14: Object Oriented Programming Lecture 5: Refactoring by Inheritance and Delegation - A simple Design Pattern for animation applets, A Generic Function Plotter

A Generic Double buffered Animation Applet

What do we need to do? We need to create a background image. We need to override the update()

method. We need a method to do the drawing in

the background image. We can extend and reuse the simple

Applet to define a generic Animation Applet

Page 15: Object Oriented Programming Lecture 5: Refactoring by Inheritance and Delegation - A simple Design Pattern for animation applets, A Generic Function Plotter

DoubleBuffered Animation Applet – Refactoring the applet

Public class abstract DBAnimationApplet extends AnimationApplet{

...

Graphics backGraphics;

Image backImage;

Dimension dim;

Boolean doubleBuffered;

...

}

Page 16: Object Oriented Programming Lecture 5: Refactoring by Inheritance and Delegation - A simple Design Pattern for animation applets, A Generic Function Plotter

The init() method

Public final void init(){dim = getSize();backImage = new Image(dim.width, dim.height);backGraphics = backImage.getGraphics();initAnimator();

}

Protected void initAnimator(){}

Page 17: Object Oriented Programming Lecture 5: Refactoring by Inheritance and Delegation - A simple Design Pattern for animation applets, A Generic Function Plotter

The update() method...Public final void update(Graphics g){

if(doubleBuffered){paintFrame(backGraphics);g.drawImage(backImage,0,0,this);

}elsesuper.update();

}

Public void paint(Graphics g){paintFrame(g);

}

Page 18: Object Oriented Programming Lecture 5: Refactoring by Inheritance and Delegation - A simple Design Pattern for animation applets, A Generic Function Plotter

The constructors

Protected DBAnimationApplet(boolean db){

this.doubleBuffered = db;}

Protected DBAnimationApplet(){this.doubleBuffered = true;

}

Page 19: Object Oriented Programming Lecture 5: Refactoring by Inheritance and Delegation - A simple Design Pattern for animation applets, A Generic Function Plotter

How do we use the DoubleBuffered Animation Applet?

1. Extend the DBAnimationApplet 2. Use the appropriate constructor to

choose doublebuffer/not doublebuffer 3. Define the abstract paintFrame()

method ...and that is it

Page 20: Object Oriented Programming Lecture 5: Refactoring by Inheritance and Delegation - A simple Design Pattern for animation applets, A Generic Function Plotter

Design by Abstraction

Designing generic components Reusable Extensible

Using: Abstract classes Interfaces Design patterns (and idioms)

Without having to modify the code!

Page 21: Object Oriented Programming Lecture 5: Refactoring by Inheritance and Delegation - A simple Design Pattern for animation applets, A Generic Function Plotter

Example

An applet for plotting functions.

Should be easy to adapt for different functions

A generic applet that captures the common code

Page 22: Object Oriented Programming Lecture 5: Refactoring by Inheritance and Delegation - A simple Design Pattern for animation applets, A Generic Function Plotter

A generic plotter

Page 23: Object Oriented Programming Lecture 5: Refactoring by Inheritance and Delegation - A simple Design Pattern for animation applets, A Generic Function Plotter

The class Plotter

Factoring by inheritance:

public class Plotter extends Japplet

public init: read parameters form html-file size parametersscaling parameters

public paint: draw the coordinate axis draw the function graph in the interval given by the parameters!

Page 24: Object Oriented Programming Lecture 5: Refactoring by Inheritance and Delegation - A simple Design Pattern for animation applets, A Generic Function Plotter

The class Plotter

What function?

A function can be implemented by a method:

public double func(double x){???}

better:

protected abstract double func(double x);

which also forces the class to be abstract! It has to be extendedfor instances to be allowed!public abstract class Plotter extends Japplet

Page 25: Object Oriented Programming Lecture 5: Refactoring by Inheritance and Delegation - A simple Design Pattern for animation applets, A Generic Function Plotter

Plotting a function

public class CosPlotter extends Plotter{ protected double func(double x){

return Math.cos(x); }} Or

public class SinPlotter extends Plotter{ protected double func(double x){

return Math.sin(x); }}

Page 26: Object Oriented Programming Lecture 5: Refactoring by Inheritance and Delegation - A simple Design Pattern for animation applets, A Generic Function Plotter

Looking inside Plotter

public abstract class Plotter extends Japplet{

private int w,h,xorigin,yorigin,xratio,yratio;private Color color = Color.black;

protected abstract double func(double x);

public void init(){w = Integer.parseInt(getParameter(“width”));h = Integer.parseInt(getParameter(“height”));xorigin = ...yorigin = ...xratio = ...yratio = ...

}

Page 27: Object Oriented Programming Lecture 5: Refactoring by Inheritance and Delegation - A simple Design Pattern for animation applets, A Generic Function Plotter

Looking inside Plotter

public void paint(Graphics g){drawCoordinates(g);plotFunction(g);

}

private void plotFunction(Graphics g){for(int px = 0; px < dim.width; px ++){ try{

double x =(double)(px - xorigin)/(double)xratio;double y =func(x);int py = yorigin - (int)(y * yratio);g.fillOval(px-1,py-1,3,3);

}catch(Exception e){}}

}

Page 28: Object Oriented Programming Lecture 5: Refactoring by Inheritance and Delegation - A simple Design Pattern for animation applets, A Generic Function Plotter

Factoring by inheritance

Design pattern: TEMPLATE

In the abstract class a template method calls (plotFunction)

a hook method (func) that is left abstract!

Page 29: Object Oriented Programming Lecture 5: Refactoring by Inheritance and Delegation - A simple Design Pattern for animation applets, A Generic Function Plotter

Factoring by delegation

Page 30: Object Oriented Programming Lecture 5: Refactoring by Inheritance and Delegation - A simple Design Pattern for animation applets, A Generic Function Plotter

The class MultiPlotter

public class MultiPlotter extends Japplet

public init as before: read parameters. public paint as before: draw coordinates and the function in the interval given by the params.

What function? A function can be implemented by an object that can do apply(double)! private Function f;

Page 31: Object Oriented Programming Lecture 5: Refactoring by Inheritance and Delegation - A simple Design Pattern for animation applets, A Generic Function Plotter

The interface Function

We need a type Function for objects that can do

double apply(double x)

Now, we want this method to behave sometimes as cos, sin, or other function. We leave the implementationthus unspecified and just define

public interface Function{ public double apply(double x);}

Page 32: Object Oriented Programming Lecture 5: Refactoring by Inheritance and Delegation - A simple Design Pattern for animation applets, A Generic Function Plotter

MultiPlotter

We can now plot a number of functions in the same applet (By having an array with Functions and an array with Colors)

We have to offer a method to add functions

We have to decide when/how to add the functions.

Page 33: Object Oriented Programming Lecture 5: Refactoring by Inheritance and Delegation - A simple Design Pattern for animation applets, A Generic Function Plotter

MultiPlotter

Let the class that adapts (extends) MultiPlotter define init() where

Parameters are read Functions are added (using the method

for doing so) A bad thing:

what happens if the programmer forgets to read the parameters?

Let init be a template method and use a hook to allow the new class to add functions!

Page 34: Object Oriented Programming Lecture 5: Refactoring by Inheritance and Delegation - A simple Design Pattern for animation applets, A Generic Function Plotter

MultiPlotter

public abstract class MultiPlotter extends Japplet

private int w, h, xorigin, yorigin, xratio, yratio; private Function [] functions; private Color [] colors;

public final void init(){/* read parameters; */functions = new Function[max];colors = new Color[max];initMultiPlotter();

}

protected abstract void initMultiPlotter();

Page 35: Object Oriented Programming Lecture 5: Refactoring by Inheritance and Delegation - A simple Design Pattern for animation applets, A Generic Function Plotter

MultiPlotter.plotFunctions

private void plotFunctions(Graphics g){ for(int i = 0; i < numOfFunctions; i++){ g.setColor(colors[i]); for(int px = 0; px < dim.width; px ++){

try{double x = (double)(px ...double y = functions[i].apply(x);int py = yorigin - ...g.fillOval(px-1,py-1,3,3);

}catch(Exception e){}}

}}

Page 36: Object Oriented Programming Lecture 5: Refactoring by Inheritance and Delegation - A simple Design Pattern for animation applets, A Generic Function Plotter

Plotting sin and cos

public class SinCos extends MultiPlotter{ protected void initMultiPlotter(){ addFunction(new Sin(),Color.red);

addFunction(new Cos(),Color.blue); }}

public class Cos implements Function{ public double apply(double x){ return Math.cos(x); }}

Page 37: Object Oriented Programming Lecture 5: Refactoring by Inheritance and Delegation - A simple Design Pattern for animation applets, A Generic Function Plotter

Plotting Sin and Cos

Page 38: Object Oriented Programming Lecture 5: Refactoring by Inheritance and Delegation - A simple Design Pattern for animation applets, A Generic Function Plotter

Design Guidelines

Maximize adaptability (extensibility)The more extensible a component is, the better chances it will be reused

Minimize risk for missuse!(make init a final method and force the definition of initMultiPlotter instead of allowing for redefinition of init!)

Page 39: Object Oriented Programming Lecture 5: Refactoring by Inheritance and Delegation - A simple Design Pattern for animation applets, A Generic Function Plotter

Factoring by delegation

Design pattern: STRATEGY

In the context (the general class, MultiPlotter) one or more instances of strategy objects

(Function[] functions) some concrete strategies (classes implementing the strategy: Cos, Sin)