Additional Design Pattern Examples Design Patterns--Factory Method
Total Page:16
File Type:pdf, Size:1020Kb
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 Application getTitle( ) * Edits 1 newDocument( ) newDocument( ) openDocument( ) openDocument( ) ... ... MyDocument Problem: How can an Application object newDocument( ) create instances of specific document classes openDocument( ) without being application-specific itself. ... 2 Factory Method--Continued Use of a document creation “factory”: Document Application getTitle( ) * Edits 1 newDocument( ) newDocument( ) openDocument( ) openDocument( ) ... ... 1 requestor * Requests-creation creator 1 <<interface>> MyDocument DocumentFactoryIF newDocument( ) createDocument(type:String):Document openDocument( ) ... DocumentFactory creates 1 createDocument(type:String):Document The Factory Method Pattern Product Uses CreationRequestor * 1 Operation1( ) newDocument( ) Operation2( ) ... … 1 requestor * Requests-creation creator 1 ConcreteProduct <<interface>> Operation1( ) FactoryIF Operation2( ) createProduct(discriminator):Product … Creates Factory 1 createProduct(discriminator):Product 3 Factory Example--Encrypted Sockets Socket Encryption * Encrypts-and-decrypts-bytes encryptor/decryptor 1 encrypedOutputStream( ) byte source decrypedInputStream( ) EncryptedSocket <<constructor>> encryptedSocket(key, EncryptionFacoryIF) <<misc.>> DESencryption RSAencryption getInputStream( ) getOutputStream( ) * * 1 requestor Requests-creation * creator <<interface>> EncryptionFactoryIF createEncryption(key):Encryption Creates Creates 1 EncryptionFactory 1 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 * This method returns an OutputStream that * streams of bytes. * encrypts the bytes written to it and writes */ * the encrypted bytes to the given OutputStream. abstract public class Encryption { * @param out The OutputStream that the private Key key; * OutputStream returned by this method /** * will write encrypted bytes to. * Constructor */ * @param key The key to use to perform abstract OutputStream encryptOutputStream * the encryption. (OutputStream out); */ /** public Encryption(Key key) { * This method returns an InputStream that this.key = key; * decrypts the stream of bytes that it reads from } // Constructor(Key) * the given InputStream. * @param in The InputStream that the /** * InputStream returned by this * Return the key this object used for * method will read bytes from. * encryption and decryption. */ */ abstract InputStream decryptInputStream protected Key getKey() { (InputStream in); return key; } // class Encrypt } // getKey() 6 A More Streamlined Version of Factory Method uses Creator … Product FactoryMethod( ) product=FactoryMethod( ) AnOperation( ) ... creates ConcreteCreator ConcreteProduct 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 WidgetFactory Client CreateScrollBar( ) Window CreateWindow( ) uses PMWindow MotifWindow MotifWidgetFactory creates PMWidgetFactory uses CreateScrollBar( ) CreateScrollBar( ) ScrollBar CreateWindow( ) CreateWindow( ) creates PMScrollBar MotifScrollBar creates creates Abstract Factory Pattern Structure uses AbstractFactory Client CreateProductA( ) AbstractProductA CreateProductB( ) uses ProductA2 ProductA1 creates ConcreteFactory1 ConcreteFactory2 uses CreateProductA( ) CreateProductA( ) AbstractProductB CreateProductB( ) CreateProductB( ) 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( ) component.Draw( ) ScrollDecorator BorderDecorator ScrollPosition BorderWidth super.Draw( ) Draw( ) Draw( ) DrawBorder( ) ScrollTo( ) DrawBorder( ) Decorator Pattern--General Structure AbstractComponent 1 Operation( ) ... component ConcreteComponent AbstractDecorator 1 Operation( ) Operation( ) component.Operation( ) ConcreteDecoratorA ConcreteDecoratorB AddedState AddedState super.Operation( ) Operation( ) Operation( ) AddedBehavior( ) AddedBehavior( ) 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