Download Additional Design Pattern Examples Design Patterns

Survey
yes no Was this document useful for you?
   Thank you for your participation!

* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project

Document related concepts
no text concepts found
Transcript
Additional Design Pattern Examples
• Creational
– Factory method
– Abstract factory
• Structural
– Decorator
– Adapter
• Behavioral
– Observer
Design Patterns--Factory Method
• Intent--Permit a class to be reuseable with
arbitrary data types. Specifically, allow the
class to be independent of the classes it
instantiates
– Define an interface for object creation.
– Let subclasses decide which class to instantiate.
• Motivation
– Useful for development of frameworks
1
Factory Method--Continued
• Consider a document-processing framework
– High-level support for creating, opening, saving
documents
– Consistent method calls for these commands,
regardless of document type (word-processor,
spreadsheet, etc.)
– Logic to implement these commands delegated
to specific types of document objects.
– May be some operations common to all
document types.
Factory Method--Continued
Document Processing Example-General Framework:
Document
getTitle( )
*
newDocument( )
openDocument( )
...
MyDocument
newDocument( )
openDocument( )
...
Application
Edits
1
newDocument( )
openDocument( )
...
Problem: How can an Application object
create instances of specific document classes
without being application-specific itself.
2
Factory Method--Continued
Use of a document creation “factory”:
Document
Application
getTitle( )
*
newDocument( )
openDocument( )
...
*
1
Edits
newDocument( )
openDocument( )
...
1 requestor
Requests-creation
creator 1
<<interface>>
MyDocument
DocumentFactoryIF
newDocument( )
openDocument( )
...
createDocument(type:String):Document
DocumentFactory
creates
1 createDocument(type:String):Document
The Factory Method Pattern
Product
Operation1( )
Operation2( )
…
Uses
*
CreationRequestor
1
newDocument( )
...
1 requestor
Requests-creation
*
creator 1
<<interface>>
ConcreteProduct
FactoryIF
Operation1( )
Operation2( )
…
createProduct(discriminator):Product
Creates
Factory
1 createProduct(discriminator):Product
3
Factory Example--Encrypted Sockets
Socket
Encryption
encrypedOutputStream( )
decrypedInputStream( )
DESencryption
*
* Encrypts-and-decrypts-bytes
encryptor/decryptor
1 byte source
RSAencryption
*
EncryptedSocket
<<constructor>>
encryptedSocket(key, EncryptionFacoryIF)
<<misc.>>
getInputStream( )
getOutputStream( )
1 requestor
Requests-creation
* creator
<<interface>>
EncryptionFactoryIF
createEncryption(key):Encryption
Creates
Creates
1
1
EncryptionFactory
createEncryption(key):Encryption
Factory Example--Java Implementation
import java.io.InputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.net.Socket;
import java.security.Key;
import java.security.NoSuchAlgorithmException;
/**
* This class extends socket so that the stream of bytes that goes over the net is encrypted.
*/
public class EncryptedSocket extends Socket {
private static Encryption crypt;
private Key key;
/**
* Constructor
* @param key The key to use for encryption and decryption. This object will determine the
*
encryption technique to use by calling the key object's getAlgorithm() method.
* @param factory The Factory object to use to create Encryption
*
objects.
* @exception NoSuchAlgorithmException if the key specifies an encryption technique that
*
is not available.
*/
4
Java Implementation--Continued
public EncryptedSocket(Key key, EncryptionFactoryIF factory) throws NoSuchAlgorithmException {
this.key = key;
crypt = factory.createEncryption(key);
} // Constructor(Key, EncryptionFactoryIF)
/**
* Returns an input stream for this socket that decrypts the inbound stream of bytes.
*
* @return an input stream for reading decrypted bytes from this socket.
* @exception IOException if an I/O error occurs when creating the input stream.
*/
public InputStream getInputStream() throws IOException {
return crypt.decryptInputStream(super.getInputStream());
} // getInputStream()
/**
* Returns an output stream for this socket that encrypts theoutbound stream of bytes.
*
* @return an output stream for reading decrypted bytes from this socket.
* @exception IOException if an I/O error occurs when creating the output stream.
*/
public OutputStream getOutputStream() throws IOException {
return crypt.encryptOutputStream(super.getOutputStream());
} // getOutputStream()
} // class EncryptedSocket
Java Implementation--Continued
import java.security.Key;
import java.security.NoSuchAlgorithmException;
/**
* This interface must be implemented by all factory classes used to create instances of
* subclasses of Encryption.
*/
public interface EncryptionFactoryIF {
/**
* This method returns an instance of the appropriate subclass of Encryption as determined
* from information provided by the given Key object.
* @param key The key that will be used to perform the encryption.
*/
public Encryption createEncryption(Key key) throws NoSuchAlgorithmException;
} // interface EncryptionFactoryIF
5
Java Implementation--Continued
/**
* This class creates instances of appropriate subclasses of Encryption.
* The appropriate subclass is determined by calling the Key object's
*/
public class EncryptionFactory implements EncryptionFactoryIF {
/**
* This method returns an instnace of the appropriate subclass of Encryption as determined
* from information provided by the given Key object's getAlgorithm method.
* @param key The key that will be used to perform the encryption.
*/
public
Encryption createEncryption(Key key) throws NoSuchAlgorithmException{
String algorithm = key.getAlgorithm();
if ("DES".equals(algorithm))
return new DESEncryption(key);
if ("RSA".equals(algorithm))
return new RSAEncryption(key);
throw new NoSuchAlgorithmException(algorithm);
} // createEncryption(Key)
} // class EncryptionFactory
Java Implementation--Continued
/**
* Abstract class to encrypt/decrypt
* streams of bytes.
*/
abstract public class Encryption {
private Key key;
/**
* Constructor
* @param key The key to use to perform
*
the encryption.
*/
public Encryption(Key key) {
this.key = key;
} // Constructor(Key)
/**
* Return the key this object used for
* encryption and decryption.
*/
protected Key getKey() {
return key;
} // getKey()
/**
* This method returns an OutputStream that
* encrypts the bytes written to it and writes
* the encrypted bytes to the given OutputStream.
* @param out The OutputStream that the
*
OutputStream returned by this method
*
will write encrypted bytes to.
*/
abstract OutputStream encryptOutputStream
(OutputStream out);
/**
* This method returns an InputStream that
* decrypts the stream of bytes that it reads from
* the given InputStream.
* @param in The InputStream that the
*
InputStream returned by this
*
method will read bytes from.
*/
abstract InputStream decryptInputStream
(InputStream in);
} // class Encrypt
6
A More Streamlined Version of
Factory Method
Product
ConcreteProduct
Creator
uses
FactoryMethod( )
AnOperation( )
creates
…
product=FactoryMethod( )
...
ConcreteCreator
FactoryMethod( )
return new ConcreteProduct
The Abstract Factory Pattern
• Intent:
– Provide an interface for creating families of
related or dependent objects without specifying
their concrete classes
• Also Known as:
– kit
– toolkit
7
Abstract Factory Pattern-- Motivation
uses
Client
WidgetFactory
Window
CreateScrollBar( )
CreateWindow( )
uses
PMWindow MotifWindow
MotifWidgetFactory
PMWidgetFactory
CreateScrollBar( )
CreateWindow( )
CreateScrollBar( )
CreateWindow( )
creates
ScrollBar
uses
creates
PMScrollBar
MotifScrollBar
creates
creates
Abstract Factory Pattern Structure
AbstractFactory
uses
Client
AbstractProductA
CreateProductA( )
CreateProductB( )
uses
ProductA2
ProductA1
creates
ConcreteFactory1
CreateProductA( )
CreateProductB( )
ConcreteFactory2
CreateProductA( )
CreateProductB( )
AbstractProductB
uses
creates
ProductB2
ProductB1
creates
creates
8
Structural Patterns--Decorator
• Intent
– Extend the functionality of an object without
subclassing.
– Allow object functionality to be extended and
restricted dynamically.
• Also known as
– wrapper pattern
Decorator Pattern Example
• Consider a TextView object
– displays text in a window
– no scroll bars
– no border
• Want to be able to extend text view to
permit scrollbars and borders
• Don’t want to use inheritance to extend
functionality of TextView.
• Solution: Use composition of Textview
object with “decorator” objects
9
Decorator Example--Continued
Visual Component
1
Draw( )
...
component
TextView
Decorator
1
Draw( )
Draw( )
ScrollDecorator
ScrollPosition
Draw( )
ScrollTo( )
component.Draw( )
BorderDecorator
BorderWidth
Draw( )
DrawBorder( )
super.Draw( )
DrawBorder( )
Decorator Pattern--General Structure
AbstractComponent
1
Operation( )
...
ConcreteComponent
component
AbstractDecorator
1
Operation( )
Operation( )
ConcreteDecoratorA
AddedState
Operation( )
AddedBehavior( )
component.Operation( )
ConcreteDecoratorB
AddedState
Operation( )
AddedBehavior( )
super.Operation( )
AddedBehavior( )
10
Decorator Pattern--Java Code Example
abstract class VisualComponent( ) {
public void Draw( );
public void Resize( );
…
} // class VisualComponent
abstract class Decorator extends VisualComponent {
private VisualComponent component;
public Decorator (VisualComponent comp) {
this.component = comp;
} // constructor
public Draw( ) {
component.Draw( );
} // Draw
public Resize( ) {
component.resize( );
}// Resize
...
}// class Decorator
Decorator Example--Continued
class BorderDecorator extends Decorator {
private int width;
public BorderDecorator(VisualComponent comp, int BorderWidth) {
super(comp); // call constructor of parent class
this.width = BorderWidth;
} // Constructor
private void DrawBorder {
… // code to implement Draw Border method
} // DrawBorder
public Draw( ) {
super.Draw( );
DrawBorder(width);
} // Draw
11
Decorator Pattern Code--Continued
class ScrollDecorator extends Decorator {
private int position = 0;
public ScrollDecorator(VisualComponent comp) {
super(comp); // call constructor of parent class
} // Constructor
private void ScrollTo(int newposition) {
… // code to implement ScrollTo method
} // ScrollTo
private void DrawScroll( ) {
… // code to implement DrawScroll method
} // DrawScroll
public Draw( ) {
super.Draw( );
DrawScroll;
} // Draw
Decorator Pattern Code--Continued
Now we can create a text object with scroll bar and border
as follows:
TextView text = new TextView();
ScrollDecorator stext = new ScrollDecorator(text);
VisualComponent bstext = new BorderDecorator(stext);
12
Decorator Pattern Example--Object
Composition
bstext
stext
Draw
delegates
Draw delegates Draw
DrawBorder
DrawScroll
text
ScrollTo(x)
(Note that client
would require knowledge of
the stext object
Structural Pattern--Adapter
• Intent: Translates between an interface
expected by clients and the interface of
otherwise incompatible objects.
• Motivation:
– allows classes to work together that otherwise
couldn’t
– permits you to use an existing class that doesn’t
have the interface that you need.
13
Adapter Pattern--General Structure
Class Adapter:
Client
<<interface>>
Target
Adaptee
Request( )
SpecificRequest( )
Adapter
Request( )
SpecificRequest( )
Object Adapter:
Client
<<interface>>
Target
Adaptee
SpecificRequest( )
Request( )
Adapter
Request( )
adaptee
adaptee.SpecificRequest( )
Behavioral Patterns--Observer
• Intent--Allow multiple dependent objects to
be notified when the state of an object
changes.
• Also known as: publisher-subscriber
14
Observer Pattern--General Structure
observed by
Subject
Attach(observer)
Detach(observer)
Notify( )
Observer
1
Update( )
*
for all o in observers {
o.Update( )
}
ConcreteSubject
subject
ConcreteObserver
subjectState
observerState
Update( )
return SubjectState
GetState( )
SetState( )
observerState =
subject.GetState( )
Observer--Use of a Multicaster
Registers
<<interface>>
ObservableIF
(to receive notifications)
<<interface>>
0..*
ObserverIF
Update( )
1
addObserver(:ObserverIF)
removeObserver(:ObserverIF)
0..*
Notifies
Observable
Observer
1
1
1
1
Registers-observers
Notifies
Multicaster
addObserver(:ObserverIF)
removeObserver(:ObserverIF)
15
Observer and Adapter Pattern
Example--The Java Event Model
• Indirect coupling between an object that
fields an event and other objects interested
in the event (listeners)
• based on the observer pattern
• An observed component needs no
knowledge about the number and structure
of listeners
• Such loose coupling creates a plug-n-play
architecture capability
Java Events
• Public methods and events are used for
communication with the outside world
• Strong typing is enforced through interface
classes which must be implemented by both
the observed (alternatively the multicaster)
and observer
• Examples from the Advanced Windowing
Tool Kit (AWT)
– Listener interfaces and adapters
16
More about Java Events
• Events are a class hierarchy
• Events are not usually changed as they are
passed between objects
• Events have public attributes and operations
used for its interpretation by a listener
• Synchronization can cause deadlocks if the
observed object holds locks
java.awt.event Events
ActionEvent
AdjustmentEvent
ContainerEvent
FocusEvent
KeyEvent
AWTEvent
Java.awt-events
ComponentEvent
Abstract
InputEvent
MouseEvent
itemEvent
PaintEvent
TextEvent
WindowEvent
17
java.awt.event Listener Interfaces
Interface
ActionListener
Interface
AdjustmentListener
EventListener
java.util
Interface
CoomponentListener
abstract
ComponentAdapter
Interface
ContainerListener
abstract
ContainerAdapter
Interface
FocusListener
abstract
FocusAdapter
Interface
ItemListener
Interface
KeyListener
Interface
MouseListener
abstract
KeyAdapter
abstract
MouseListenerAdapter
Interface
MouseMotionListener
Interface
TextListener
Interface
WindowListener
abstract
MouseMotionAdapter
abstract
WindowAdapter
Graphical User Interface Example
This string is an attribute of textField
java.awt.textField
java.awt.button
18
Sends Event to Every Added Listener
AWTEventMulticaster
ActionPerformed();
Add();
Remove();
Add
Remove
ActionPerformed
Interface ActionListener
Implements
ActionPerformed();
multicaster
->Add(l);
ZapTextField
Button
AddActionListener(ActionListoner l);
performActionEvent(ACtionEvent e);
Implements
AddActionListener ActionPerformed();
Multicaster looks like an ActionListener Object giving:
actionListener.ActionPerformed(e);
Object
TextField
Component
TextComponent
Methods:
int getCaretPosition();
synchronized
getSelectedText();
sychronized in
getSelectionEnd();
setText(String t).
....
Attribute:
String text
int columns
char EchoChar
Methods:
synchronized void addActionListener(ActionListener l);
boolean echoCharIsSet();
int getColumns();
char getEchoChar();
Dimension getMinimumSize();
synchronized void
removeActionListener(ActionListener l);
void setColumns(int Columns);
void setEchoChar(char C);
protected void processActionEvent(ActionEvent e);
protected void processEvent(AWTEvent e);
19
Component
Methods:
synchronized void addMouseListener(MouseListener l);
protected void processMouseEvent(MouseEvent e);
protected void processMouseMotionEvent(MouseMotionEvent e);
...
public boolean IsEnabled();
Button
Attributes:
string label;
Methods:
String getLabel();
synchronized void setLabel(String label);
synchronized void addActionListener(ActionListener l);
...
Button Attaches Observer
Adds the specified action listener to receive action events from
this button. Action events occur when a user presses or releases
the mouse over this button.
public synchronized void addActionListener(ActionListener l) {
actionListener =
AWTEventMulticaster.add(actionListener, l);
}
20
Button Sends Action Event to all
Observers
protected void processActionEvent(ActionEvent e) {
if (actionListener != null) {
actionListener.actionPerformed(e);
} }
Extended Text Field as an Observer
public class ZapTextField extends TextField implements
ActionListener
{
public ZapTextField() {attachButton();}
protected void attachButton() {
button1.addActionListener(this);
}
public void actionPerformed(ActionEvent e) {
this.setText(”~~~~~~~~~");
}
}
21
Adapters in Java API
• Adapters are implemented as classes with
stubbed methods
• Classes using the adapter extend only those
stubbed methods that they need.
• Without the use of an adapter, a class that
implements and interface would have to
implement all of the methods in that
interface, even if it isn’t interested in all of
them.
Mouse Adapter
Interface MouseListener
public
public
public
public
public
abstract void mouseclicked(MouseEvent e);
abstract void mouseEntered(MouseEvent e);
abstract void mouseExited(MouseEvent e);
abstract void mousePressed(MouseEvent e);
abstract void mouseReleased(MouseEvent e);
Implements
MouseAdapter
public void mouseclicked(MouseEvent e) {}
public void mouseEntered(MouseEvent e) {}
public void mouseExited(MouseEvent e) {}
public void mousePressed(MouseEvent e) {}
public void mouseReleased(MouseEvent e) {}
Extends
Button
public void mouseclicked(MouseEvent e) {
...
}
22
Use of Adapters in the Java API
Event Handling using an anonymous inner class:
Button pushMe = new Button(“Push Me”)
pushMe.addActionListener(new ActionListener( ) {
public void actionPerformed(actionEvent evt) {
doSomethingFantastic(ActionEvent)
} // actionPerformed(ActionEvent)
} );
add (pushMe);
.
.
.
Note: The Java API contains a number of abstract adapter classes-e.g. WindowAdapter in AWT (InternalFrameAdapter in Swing). Look
at the Java API Specification and determine the purpose of these adapters.
23