CS 635 Advanced Object-Oriented Design & Programming Spring Semester, 2001 Decorator, Chain of Responsibility, OO Recursion |
||
---|---|---|
© 2001, All Rights Reserved, SDSU & Roger Whitney San Diego State University -- This page last updated 19-Apr-01 |
Decorator
Changing the Skin of an Object
Class Structure
Runtime Structure
Motivation - Text Views
A text view has the following features:
Solution 1 - Use Object Composition
class TextView { Border myBorder; ScrollBar verticalBar; ScrollBar horizontalBar; public void draw() { myBorder.draw(); verticalBar.draw(); horizontalBar.draw(); code to draw self } etc. }
But TextView knows about all the variations!
New type of variations require changing TextView
(and any other type of view we have)
Solution 2 - Use Decorator
Object Composition Inside out
Change the skin of an object not it guts
TextView has no borders or scrollbars!
Add borders and scrollbars on top of a TextView
Runtime Structure
Applicability
Use Decorator:
if ( aComponent instanceof TextView ) blah
Implementation Issues
Keep Decorators lightweight
Don't put data members in VisualComponent
Have Decorator forward all component operations
Three ways to forward messages
Examples
Java Streams
import java.io.*; import sdsu.io.*; class ReadingFileExample { public static void main( String args[] ) throws Exception { FileInputStream inputFile; BufferedInputStream bufferedFile; ASCIIInputStream cin; inputFile = new FileInputStream( "ReadingFileExample.java" ); bufferedFile = new BufferedInputStream( inputFile ); cin = new ASCIIInputStream( bufferedFile ); System.out.println( cin.readWord() ); for ( int k = 1 ; k < 4; k++ ) System.out.println( cin.readLine() ); } }
Insurance
Insurance policies have payment caps for claims
Sometimes the people with the same policy will have different caps
A decorator can be used to provide different caps on the same policy object
Similarly for deductibles & copayments
Chain of Responsibility
Intent
Avoid coupling the sender of a request to its receiver by giving more than one object a chance to handle the request. Chain the receiving objects and pass the request along the chain until an object handles it.
Class Structure
Sample Object Structure
Participants
Handler
Motivation
Context Help System
When to Use
When more than on object may handle a request, and the handler isn't known a priori
When you want to issue a request to one of several objects without specifying the receiver explicitly
When the set of objects that can handle a request should be specified dynamically
How does this differ from Decorator?
Chain of Command
Like the military
Implementation Issues
The successor chain
Representing Requests
abstract class HardCodedHandler { private HardCodedHandler successor; public HardCodedHandler( HardCodedHandler aSuccessor) { successor = aSuccessor; } public void handleOpen() { successor.handleOpen(); } public void handleClose() { successor.handleClose(); } public void handleNew( String fileName) { successor.handleClose( fileName ); } }
Representing Requests
abstract class SingleHandler { private SingleHandler successor; public SingleHandler( SingleHandler aSuccessor) { successor = aSuccessor; } public void handle( String request) { successor.handle( request ); } } class ConcreteOpenHandler extends SingleHandler { public void handle( String request) { switch ( request ) { case "Open" : do the right thing; case "Close" : more right things; case "New" : even more right things; default: successor.handle( request ); } } }
Representing Requests
abstract class SingleHandler { private SingleHandler successor; public SingleHandler( SingleHandler aSuccessor) {successor = aSuccessor; } public void handle( Request data) { successor.handle( data ); } } class ConcreteOpenHandler extends SingleHandler { public void handle( Open data) { // handle the open here } } class Request { private int size; private String name; public Request( int mySize, String myName) { size = mySize; name = myName; } public int size() { return size; } public String name() { return name;} } class Open extends Request {// add Open specific stuff here} class Close extends Request { // add Close specific stuff here}
Object-Oriented Recursion
Recursive Delegation
A method polymorphically sends its message to a different receiver
Eventually a method is called that performs the task
The recursion then unwinds back to the original message send
Example
class BinarySearchTree { Node root boolean containsKey( Object key ) { return root.containsKey(key); } String toString() { return "Tree( " + root.toString() + ")"; } blah }
Example Continued class BinaryNode implements Node { Node left; Node right; Object key; Object value; boolean containsKey( Object key ) { if this.key == key return true; if this.key < key return right.containsKey(key); if this.key > key return left.containsKey( key); } String toString() { return "( " + left.toString() + key + right.toString() + ")"; } blah } class NullNode implements Node { boolean containsKey( Object key ) { return false; } String toString() { return " "; } blah }
Copyright ©, All rights reserved.
2001 SDSU & Roger Whitney, 5500 Campanile Drive, San Diego, CA 92182-7700 USA.
OpenContent license defines the copyright on this document.
Previous    visitors since 19-Apr-01    Next