Survey
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
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