creational design patterns

85
Creational Design Patterns Factory Method Abstract Factory Builder Prototype Singleton Object Pool

Upload: liesel

Post on 10-Feb-2016

29 views

Category:

Documents


1 download

DESCRIPTION

Creational Design Patterns. Factory Method Abstract Factory Builder Prototype Singleton Object Pool. CDP - Factory Method. Synopsis: Need for a class for reuse with arbitrary data types. - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: Creational Design Patterns

Creational Design Patterns

Factory Method

Abstract Factory

Builder

Prototype

Singleton

Object Pool

Page 2: Creational Design Patterns

CDP - Factory Method

Synopsis:

Need for a class for reuse with arbitrary data types.

Reusable class remains independent of the classes it instantiates by delegating the choice of which class to instantiate to another object and referring to the newly created object through a common interface.

Context:

Creates a framework to support instantiations of various data types.

Page 3: Creational Design Patterns

CDP - Factory Method

Forces:

Provide services (methods) in a way transparent to classes using those services.

Solution:

Proxy object and the service providing object must either be instances of a common super class or implement a common interface.

Consequences:

Could introduce new failure points.

Page 4: Creational Design Patterns

CDP - Factory Method - ExampleYou have an application such as MS Office.

You want to perform some common functions with all the files.

Example of common functions might be open file, save file, etc.

The only difference is that the functions are done on different file types such as word doc files, excel xls files and PowerPoint ppt files.

You could write several independent functions for each of the different types but the code would be very similar with only the data type as a difference.

The factory method allows you to build a framework to perform the common functions with only a few classes that reused for each type.

Page 5: Creational Design Patterns

Manage Files

file commands

ManageDoc Files

doc file commands

ManageXls Files

xls file commands

ManagePpt Files

ppt file commands

Make one Function

CDP - Factory Method - Example

Page 6: Creational Design Patterns

CDP - Factory Method - Example

Document Applicationedits 1

*

MyDocument May be doc, xls, or ppt.

Page 7: Creational Design Patterns

CDP - Factory Method - Example

Document Applicationedits 1

*

MyDocument

DocumentFactoryIF

Requests creation

DocumentFactory

creates

Page 8: Creational Design Patterns

Write to Socket

stream

CDP - Factory Method - Example

Socket

But you also wish to have strings in which you encrypt the data.And you write an encrypted DataStream and read back an encrypted Data Stream decrypt it.

string

Suppose you have a process which reads and writes a DataStream to a socket.

Read from Socket

stream Socketstring

Page 9: Creational Design Patterns

Write to Encrypted

Socket

encrypted stream

CDP - Factory Method - Example

EncryptedSocketencrypted string

Encrypt Data

string Write to Encrypted

Socket

encrypted stream

EncryptedSocketencrypted string

Read from Socket

encryptedstream

Socketencrypted stringDecrypt

Data

decrypted string

But now you realize that there are several different encryption algorithms and codes you wish to use.

Page 10: Creational Design Patterns

CDP - Factory Method - Example

Encrypt Data

string Write to Encrypted

Socket

encrypted stream

EncryptedSocketencrypted String #1

algorithm # 1

The process to encrypt differs in using many different different algorithms (function/method) and type of string output must be written for each type.

Encrypt Data

string Write to Encrypted

Socket

encrypted stream

EncryptedSocketencrypted String #2

algorithm # 2

Encrypt Data

string Write to Encrypted

Socket

encrypted stream

EncryptedSocketencrypted String #n

algorithm # n

Page 11: Creational Design Patterns

CDP - Factory Method - Example

Encrypt Data

string Write to Encrypted

Socket

encrypted stream

EncryptedSocketencrypted String

algorithm # 1

algorithm # 2

algorithm # n

The factory pattern allows you to have a framework that will handle any type of algorithm and encrypted data.

concrete product

Page 12: Creational Design Patterns

CDP - Factory Method - Example

Encryption

Socket

encrypt, decrypt 1

*

DESEncryption

EncryptedSocket

Transcription

EncryptionFactory

EncryptionFactoryIF

creates

requestCreation

creates11

*

*

*

1

Concrete Product

Product

Factory

Socket

EncryptedSocket

Interface

Creation Requester

1

2

3

4

5

6

Page 13: Creational Design Patterns

CDP - Factory Method - Example

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 to encrypt the stream of bytes over the net.

public class EncryptedSocket extends Socket {

private static Encryption crypt;

private Key key;

Encryption

Socket

encrypt, decrypt 1*

DESEncryption

EncryptedSocket

Transcription

EncryptionFactory

EncryptionFactoryIF

creates

requestCreation

creates11

*

*

*

1

Page 14: Creational Design Patterns

CDP - Factory Method - Example

// Constructor

// @param Key for encryption and decryption.

// Determines encryption technique by calling key object's getAlgorithm() method.

// @param Factory object to use to create Encryption objects.

// @exception NoSuchAlgorithmException if key specifies technique not available.

public EncryptedSocket(Key key, EncryptionFactoryIF factory)

throws NoSuchAlgorithmException {

this.key = key;

crypt = factory.createEncryption(key);

} // Constructor(Key, EncryptionFactoryIF)

Encryption

Socket

encrypt, decrypt 1*

DESEncryption

EncryptedSocket

Transcription

EncryptionFactory

EncryptionFactoryIF

creates

requestCreation

creates11

*

*

*

1

Page 15: Creational Design Patterns

CDP - Factory Method - Example

// Returns an input stream that decrypts the inbound stream of bytes.

// @return an input stream for reading decrypted bytes

// @ 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 that encrypts the outbound stream of bytes.

// @return an output stream for reading decrypted bytes

// @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

Page 16: Creational Design Patterns

CDP - Factory Method - Example

import java.io.InputStream;

import java.io.OutputStream;

import java.security.Key;

// 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()

Encryption

Socket

encrypt, decrypt 1*

DESEncryption

EncryptedSocket

Transcription

EncryptionFactory

EncryptionFactoryIF

creates

requestCreation

creates11

*

*

*

1

Page 17: Creational Design Patterns

CDP - Factory Method - Example

// This method returns an OutputStream.

// It encrypts bytes written to it.

// And it writes the encrypted bytes to the given OutputStream.

// @param out OutputStream that OutputStream returned writes encrypted bytes.

abstract OutputStream encryptOutputStream(OutputStream out);

// This method returns an InputStream.

// It decrypts the stream of bytes read from the given InputStream.// @param in InputStream that InputStream returned reads bytes.

abstract InputStream decryptInputStream(InputStream in);

} // class Encrypt

Page 18: Creational Design Patterns

CDP - Factory Method - Example

import java.security.Key;

import java.security.NoSuchAlgorithmException;

// This interface must be implemented by all factory classes

// that are used to create instances of subclasses of Encryption.

public interface EncryptionFactoryIF { // Returns an instance of appropriate subclass of Encryption.

// The instance is determined from information provided by the given Key object.

// @param key will be used to perform the encryption.

public Encryption createEncryption(Key key) throws NoSuchAlgorithmException;

} // interface EncryptionFactoryIF

Encryption

Socket

encrypt, decrypt 1*

DESEncryption

EncryptedSocket

Transcription

EncryptionFactory

EncryptionFactoryIF

creates

requestCreation

creates11

*

*

*

1

Page 19: Creational Design Patterns

CDP - Factory Method - Example

import java.security.Key;

import java.security.NoSuchAlgorithmException;

// This class creates instances of appropriate subclasses of Encryption.

//The appropriate subclass is determined by calling the Key object's

public class EncryptionFactory {

Encryption

Socket

encrypt, decrypt 1*

DESEncryption

EncryptedSocket

Transcription

EncryptionFactory

EncryptionFactoryIF

creates

requestCreation

creates11

*

*

*

1

Page 20: Creational Design Patterns

CDP - Factory Method - Example

// Returns an instanace of the appropriate subclass of Encryption.

// It is determined 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

Encryption

Socket

encrypt, decrypt 1*

DESEncryption

EncryptedSocket

Transcription

EncryptionFactory

EncryptionFactoryIF

creates

requestCreation

creates11

*

*

*

1

Page 21: Creational Design Patterns

CDP - Factory Method - Example

import java.io.InputStream;

import java.io.FilterInputStream;

import java.io.FilterOutputStream;

import java.io.OutputStream;

import java.security.Key;

// class to DES encrypt/decrypt streams of bytes.

public class DESEncryption extends Encryption {

/**

* Constructor

* @param key The key to use to perform the encryption.

*/

public DESEncryption(Key key) {super(key); } // Constructor(Key)

Encryption

Socket

encrypt, decrypt 1*

DESEncryption

EncryptedSocket

Transcription

EncryptionFactory

EncryptionFactoryIF

creates

requestCreation

creates11

*

*

*

1

Page 22: Creational Design Patterns

CDP - Factory Method - Example

// Returns an OutputStream that encrypts the bytes written to it/

// And writes the encrypted bytes to the given OutputStream.

// @param out OutputStream that OutputStream returned by this method writes encrypted bytes.

OutputStream encryptOutputStream(OutputStream out) {

return new DESEncrytpedOutputStream(out);

} // encryptOutputStream(OutputStream)

Encryption

Socket

encrypt, decrypt 1*

DESEncryption

EncryptedSocket

Transcription

EncryptionFactory

EncryptionFactoryIF

creates

requestCreation

creates11

*

*

*

1

Page 23: Creational Design Patterns

CDP - Factory Method - Example

/**

* 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.

*/

InputStream decryptInputStream(InputStream in) {

return new DESEncrytpedInputStream(in);

} // decryptInputStream(InputStream)

Encryption

Socket

encrypt, decrypt 1*

DESEncryption

EncryptedSocket

Transcription

EncryptionFactory

EncryptionFactoryIF

creates

requestCreation

creates11

*

*

*

1

Page 24: Creational Design Patterns

CDP - Abstract Factory Method

Synopsis:

Need for a class for reuse with abstract classes.

Reusable class remains independent of the classes it instanciates by delegating the choice of which class to instanciate to another object and referring to the newly created object through a common interface.

Context:

Creates a framework to support instanciations of various abstract classes.

Page 25: Creational Design Patterns

Forces:

Provide services (methods) in a way transparent to classes using those services.

Solution:

Proxy object and the service providing object must either be instances of a common super class or implement a common interface.

Consequences:

Could introduce new failure points.

CDP - Abstract Factory Method

Page 26: Creational Design Patterns

CDP - Abstract Factory Method

Displaywindows textfield

Suppose you have a textfield or any other GUI component and you wish to display it on a particular platform.

Page 27: Creational Design Patterns

CDP - Abstract Factory Method

Displaywindows textfield

Suppose you wish to display those GUI componentson various platforms.

MacOS textfield

Linix textfield

Certainly each platform expects to see different Java byte code.

Page 28: Creational Design Patterns

CDP - Abstract Factory Method

Architecture Toolkit

uses

EmberToolkit

Client

EnginolaToolkit

requestCreation

creates1*

*

1

CPUuses

EmberCPU

EnginolaCPU

creates

creates

MMU

EnginolaMMU EmberMMU

uses

Concrete FactoryConcrete Product

Abstract Factory

Request services

Page 29: Creational Design Patterns

CDP - Abstract Factory Method

// Sample client class shows how a client class can create concrete widget objects using an abstract factory

public class Client {

public void doIt () {

ArchitectureToolkit af;

af = ArchitectureToolkit.getFactory(ArchitectureToolkit.EMBER);

CPU cpu = af.createCPU();

//...

} //doIt

} // class Client

Page 30: Creational Design Patterns

CDP - Abstract Factory Method

// Abstract factory class for creating objects for remote tests on computer components.

public abstract class ArchitectureToolkit {

private static final EmberToolkit emberToolkit = new EmberToolkit();

private static EnginolaToolkit enginolaToolkit = new EnginolaToolkit();

//...

// Symbolic names to identify types of computers

public final static int ENGINOLA = 900;

public final static int EMBER = 901;

// ...

Page 31: Creational Design Patterns

CDP - Abstract Factory Method

// Returns a concrete factory object as an instance of the concrete factory class.

// It is appropriate for the given computer architecture.

// @param architecture - value indicating architecture that concrete factory returned for.

static final ArchitectureToolkit getFactory(int architecture) {

switch (architecture) {

case ENGINOLA: return enginolaToolkit;

case EMBER: return emberToolkit;

// ...

} // switch

String errMsg = Integer.toString(architecture);

throw new IllegalArgumentException(errMsg);

} // getFactory()

Page 32: Creational Design Patterns

CDP - Abstract Factory Method

// Method to create objects for remote testing CPUs.

public abstract CPU createCPU() ;

// Method to create objects for remote testing MMUs.

public abstract MMU createMMU() ;

//...

} // ArchitectureToolkit

Page 33: Creational Design Patterns

CDP - Abstract Factory Method

// This is a concrete factory class for creating objects used to perform remote tests.

// These tests are on core components of ember architecture computers.

class EmberToolkit extends ArchitectureToolkit {

// Method to create objects for remote testing ember CPUs.

public CPU createCPU() { return new EmberCPU(); } // createCPU()

// Method to create objects for remote testing ember MMUs.

public MMU createMMU() { return new EmberMMU(); } // createMMU()

//...

} // class EmberToolkit

Page 34: Creational Design Patterns

CDP - Abstract Factory Method

// This is a concrete factory class for creating objects used to perform remote tests.

// These tests are on core components of enginola architecture computers.

class EnginolaToolkit extends ArchitectureToolkit {

// Method to create objects for remote testing enginola CPUs.

public CPU createCPU() { return new EnginolaCPU(); } // createCPU()

// Method to create objects for remote testing enginola MMUs.

public MMU createMMU() { return new EnginolaMMU(); } // createMMU()

//...

} // class EnginolaToolkit

Page 35: Creational Design Patterns

CDP - Abstract Factory Method

// This is an abstract class for objects that perform remote tests on CPUs.

public abstract class CPU extends ComponentTester {

//...

} // class CPU

// This is an abstract class for objects that perform remote tests on CPUs.

public abstract class CPU extends ComponentTester {

//...

} // class CPU

Page 36: Creational Design Patterns

CDP - Abstract Factory Method

// Class for objects that perform remote tests on Ember architecture CPUs.

class EmberCPU extends CPU {

//...

} // class EmberCPU

// Class for objects that perform remote tests on Enginola architecture CPUs.

class EnginolaCPU extends CPU {

//...

} // class EnginolaCPU

Page 37: Creational Design Patterns

CDP - Abstract Factory Method

// This is an abstract class for objects that perform remote tests on MMUs.

public abstract class MMU extends ComponentTester {

//...

} // class MMU

_________________________________________________________________________

// Class for objects that perform remote tests on Enginola architecture MMUs.

class EnginolaMMU extends MMU {

//...

} // class EnginolaMMU

_________________________________________________________________________

// Class for objects that perform remote tests on Ember architecture MMUs.

public class EmberMMU extends MMU {

//...

} // class EmbeMMU

Page 38: Creational Design Patterns

CDP - Builder

Synopsis: Need to build an instance of an object depending on the type of instance needed.

Context: Allows a client object to construct a complex object by specifying only its type and content.

Forces: Program required to produce multiple external representations of the same data.

Page 39: Creational Design Patterns

Solution:

Abstract Builder builds and returns the data representation needed.

Concrete builder, subclass of abstract builder, used to build a specific kind of data representation.

Consequences:

Provides finer control over construction that other patterns.

CDP - Builder

Page 40: Creational Design Patterns

Forward E-mail

format 1

Suppose you have an e-mail gateway program. The program receives a message in MIME format and forwards them in a different format for a different kind of e-mail system.

CDP - Builder

MIME mail

Destination 1format 2

Destination 1format n

Destination 1

You have a procedure (set of methods) for each format builder routine. The methods are similar but you need multiple procedures.The builder pattern allows you to use one method for all formats.

Page 41: Creational Design Patterns

BuildFormat

format whatever

You want a class to build the format needed depending on the Destination using a builder class.

CDP - Builder

MIME mail

Destination 1

Destination 1

Destination 1

ForwardedE-Mail

Page 42: Creational Design Patterns

CDP - Builder

MessageManagermanages

PRoFMsg

MIMEMsg

MAPIMsg

creates

requestCreation

creates1*

*

MIMEParser

MessageBuilder

MAPIBuilder PROFSBuilder

OutboundMessageIF

sendsis parsed by

directs

Product

Director

ProductIF

1: receive(MIME)

2: parse(MIME)

3: build

4: send

Page 43: Creational Design Patterns

CDP - Builder (collaboration diagram)

MessageManager MIMEParser

MessageBuilder Builder:MAPIBuilder

outMsg:OutboundMessageIF

1.2: send( )

1.1: outMsg:=parse(msg:MIMEMsg)1: receive (msg:MIMEMsg)

1.1.2: to(:String)1.1.3:from(:String)1.1.4:plainText(:String)1.1.5:jpegImage(:Image)1.1.6:outMsg :=getOutboundMsg( )

1.1.1: builder:=getInstance(to:String)

1: receive(MIME) 2: parse(MIME)

3: build

4: send

Page 44: Creational Design Patterns

CDP - Builderimport java.awt.Image;

// This is an abstract builder class for building e-mail messages

abstract class MessageBuilder { // Return an object of the subclass for the e-mail message format implied by the destination address.

//@param dest The e-mail address the message is to be sent to

static MessageBuilder getInstance(String dest) {

MessageBuilder builder = null;

//...

return builder;

} // getInstance(String)

MessageManager MIMEParser

MessageBuilder Builder:MAPIBuilder

outMsg:OutboundMessageIF

1.2: send( )

1.1: outMsg:=parse(msg:MIMEMsg)1: receive (msg:MIMEMsg)

1.1.2: to(:String)1.1.3:from(:String)1.1.4:plainText(:String)1.1.5:jpegImage(:Image)1.1.6:outMsg :=getOutboundMsg( )

1.1.1: builder:=getInstance(to:String)

1: receive(MIME) 2: parse(MIME)

3: build

4: send

Page 45: Creational Design Patterns

CDP - Builder // pass the value of the "to" header field to this method.

abstract void to(String value);

// pass the value of the "from" header field to this method.

abstract void from(String value);

//...

// pass the value of the "organization" header field to this method.

void organization(String value) { }

// pass the content of a plain text body part to this method.

abstract void plainText(String content);

// pass the content of a jpeg image body part to this method.

abstract void jpegImage(Image content) ;

// complete and return the outbound e-mail message.

abstract OutboundMessageIF getOutboundMsg() ;

} // class MessageBuilder

Page 46: Creational Design Patterns

CDP - Builder // Class used to represent raw MIME e-mail messages.

// If program expanded to receive messages in formats other than MIME,

// then this will probably become an abstract class with a subclass for each type of e-mail.

public class MIMEMessage {

private byte[] rawMessage;

// Constructor @param msg A byte array containing a raw unprocessed e-mail message.

public MIMEMessage(byte[] msg) { rawMessage = msg; } // constructor(byte[])

// Return the raw bytes of an unprocessed e-mail message.

byte[] getMessage() { return rawMessage; } // getMessage()

} // class MIMEMessage

Page 47: Creational Design Patterns

CDP - Builder

import java.awt.Image;

// This is a class to parse MIME e-mail messages.

class MIMEParser {

private MIMEMessage msg; // The message being parsed

private MessageBuilder builder; // The builder object

//...

MessageManager MIMEParser

MessageBuilder Builder:MAPIBuilder

outMsg:OutboundMessageIF

1.2: send( )

1.1: outMsg:=parse(msg:MIMEMsg)1: receive (msg:MIMEMsg)

1.1.2: to(:String)1.1.3:from(:String)1.1.4:plainText(:String)1.1.5:jpegImage(:Image)1.1.6:outMsg :=getOutboundMsg( )

1.1.1: builder:=getInstance(to:String)

1: receive(MIME) 2: parse(MIME)

3: build

4: send

Page 48: Creational Design Patterns

CDP - Builder

// parse MIME message, call builder methods for message's header fields and body parts.

OutboundMessageIF parse(MIMEMessage msg) {

this.msg = msg;

builder = MessageBuilder.getInstance(getDestination());

MessagePart hdr = nextHeader();

while (hdr != null) {

if (hdr.getName().equalsIgnoreCase("to"))

builder.to((String)hdr.getValue());

else if (hdr.getName().equalsIgnoreCase("from"))

builder.from((String)hdr.getValue());

//...

hdr = nextHeader();

} // while hdr

Page 49: Creational Design Patterns

CDP - Builder MessagePart bdy = nextBodyPart();

while (bdy != null) {

if (bdy.getName().equals("text/plain")) builder.plainText((String)bdy.getValue()); //...

else if (bdy.getName().equals("image/jpeg")) builder.jpegImage((Image)bdy.getValue());

//...

bdy = nextHeader();

} // while body

return builder.getOutboundMsg();

} // parse(MIMEMessage)

private MessagePart nextHeader() {

MessagePart mp = null;

//...

return mp;

} // nextHeader()

Page 50: Creational Design Patterns

CDP - Builder

private MessagePart nextBodyPart() {

MessagePart mp = null;

//...

return mp;

} // nextBodyPart()

// return the destination e-mail address for the message

private String getDestination() {

String dest = null;

//...

return dest;

} // getDestination()

Page 51: Creational Design Patterns

CDP - Builder private class MessagePart {

private String name;

private Object value;

// Consructor

MessagePart(String name, Object value) {

this.name = name;

this.value = value;

} // Consructor(String, String)

String getName() { return name; }

Object getValue() { return value; }

} // class MessagePart

} // class MIMEParser

Page 52: Creational Design Patterns

CDP - Builder

// All classes that are used to represent outbound messages will implement this interface.

public interface OutboundMessageIF {

public void send() ;

} // interface OutboundMessageIF

MessageManager MIMEParser

MessageBuilder Builder:MAPIBuilder

outMsg:OutboundMessageIF

1.2: send( )

1.1: outMsg:=parse(msg:MIMEMsg)1: receive (msg:MIMEMsg)

1.1.2: to(:String)1.1.3:from(:String)1.1.4:plainText(:String)1.1.5:jpegImage(:Image)1.1.6:outMsg :=getOutboundMsg( )

1.1.1: builder:=getInstance(to:String)

1: receive(MIME) 2: parse(MIME)

3: build

4: send

Page 53: Creational Design Patterns

CDP - Prototype

Synopsis:

Allows creation of customized objects without knowing their exact class or details of how to create them.

Context:

Addresses how to provide a prototype for creating similar object.

Forces:

Create objects without knowing their exact class, how created or what data they represent.

Page 54: Creational Design Patterns

Solution:

Create a prototype class that implements a Prototype interface and are instantiated for being cloned.

Create a prototype builder to supply prototypical objects.

Consequences:

Additional time is spent writing prototypebuilder classes.

CDP - Prototype

Page 55: Creational Design Patterns

SelectSymbol

build symbol object

Suppose you have a CAD system that allows you to draw symbols on a screen from a symbol palette AND you wish to have the user to be able to create user defined symbols.

CDP - Prototype

symbolselection

You have a procedure (set of methods) for each symbol or you have A builder routine for the symbols. Then for a user defined symbol, youmust set up all possible things you might wish and allow the user to select methods at runtime.

user defined symbol selection

Page 56: Creational Design Patterns

SelectSymbol

build symbol selected object

You could allow an object to create a cloned object from others.

CDP - Prototype

symbolselection

The prototype object is built at runtime allowing the user to use thenewly defined symbol based on some predefined prototype.

user defined symbol selection

user defined symbol selection

BuildPrototype

Object

build symbol selected object

Page 57: Creational Design Patterns

CDP - Prototype

CharacterManageruses

Character

Hero Monster

create and register objects

CharacterLoader

<<interface>> Cloneable

PrototypeBuilder

PrototypeClient

Page 58: Creational Design Patterns

CDP - Prototype

import java.awt.Image;

// Abstract class for characters.

public abstract class Character implements Cloneable {

private String name;

private Image image;

private int strength;

//...

// Override clone to make it public. Should never have exception

public Object clone() {

try { return super.clone(); }

catch (CloneNotSupportedException e) {throw new InternalError(); } // try

} // clone()

Page 59: Creational Design Patterns

CDP - Prototype

public String getName() { return name; } // getName()

public void setName(String name) { this.name = name; } // setName(String)

public Image getImage() { return image; } // getImage(Image)

public void setImage(Image image) { this.image = image; } // setImage(Image)

public int getStrength() { return strength; } // getStrength()

public void setStrength(int strength) { this.strength = strength; } // setStrength(int)

//...

} // class Character

Page 60: Creational Design Patterns

CDP - Prototype

import java.io.BufferedInputStream;

import java.io.FileInputStream;

import java.io.InputStream;

import java.io.ObjectInputStream;

// This class loads character objects and adds them to the CharacterManager.

class CharacterLoader {

private CharacterManager mgr;

// Constructor * @param cm The CharacterManager that this object will work with.

CharacterLoader(CharacterManager cm) { mgr = cm; } // Constructor

Page 61: Creational Design Patterns

CDP - Prototype

// Load character objects from specified file.

// Exceptions needed since failure only affects the program when new character objects are not loaded.

// @param fname The name of the file to read objects from.

// @return The number of Charcter objects loaded.

int loadCharacters(String fname) {

int objectCount = 0; // The number of objects loaded

Page 62: Creational Design Patterns

CDP - Prototype // If construction of the InputStream fails, just return

try {

InputStream in;

in = new FileInputStream(fname);

in = new BufferedInputStream(in);

ObjectInputStream oIn = new ObjectInputStream(in);

while(true) {

Object c = oIn.readObject();

if (c instanceof Character) { mgr.addCharacter((Character)c); } // if

} // while

} catch (Exception e) { } // try

return objectCount;

} // loadCharacters(String)

} // class CharacterLoader

Page 63: Creational Design Patterns

CDP - Prototype import java.util.Vector;

// Class manages collection of prototypical objects for the game.

// When asked, it clones appropriate prototypical object and returns it to requesting object.

public class CharacterManager {

private Vector characters = new Vector();

//...

// Return a random character from the collection.

Character getRandomCharacter() {

int i = (int)(characters.size()*Math.random());

return (Character)((Character)characters.elementAt(i)).clone();

} // getRandomCharacter()

Page 64: Creational Design Patterns

CDP - Prototype

// Add a prototypical object to the collection.

// @param character The character to add.

void addCharacter(Character character) {

characters.addElement(character);

} // addCharacter(Character)

//...

} // class CharacterManager

Page 65: Creational Design Patterns

CDP - Prototype // instances of this class are hero characters.

public class Hero extends Character {

private int bravery;

//...

public int getBravery() {

return bravery;

} // getBravery()

public void setBravery(int bravery) {

this.bravery = bravery;

} // setBravery(int)

} // class Hero

Page 66: Creational Design Patterns

CDP - Prototype // instances of this class are monster characters.

public class Monster extends Character {

private int visciousness;

//...

public int getVisciousness() {

return visciousness;

} // getVisciousness()

public void setVisciousness(int visciousness) {

this.visciousness = visciousness;

} // setVisciousness(int)

} // class Monster

Page 67: Creational Design Patterns

CDP - Singleton

Synopsis:

Insures only one instance of a class is created.

Context:

Some classes are used to manage a resource so they require creation only once.

Forces:

Requirement for one instance of a class accessible.

Page 68: Creational Design Patterns

Solution:

A static variable that refers to the one instance of the class you wish to use as a singleton.

Consequences:

Subclassing is awkward and results in imperfectly encapsulated classes.

CDP - Singleton

Page 69: Creational Design Patterns

PlayAudio

audio

Suppose you have a audio connection (player) which plays anAudio but should now allow two audios to play at one time.

CDP - Singleton

audio playtrigger

If you do not want one audio to overlay the others (play at the same time), you will have to write a semaphore to keep multiple audiosfrom playing.

overlaying audio

Page 70: Creational Design Patterns

PlayAudio

audio

Make a singleton which acts as a semaphore to allowcreation of its playing object only once (a singleton).

CDP - Singleton

audio playtrigger

Page 71: Creational Design Patterns

CDP - Singleton

AudioClipManager Singleton

Page 72: Creational Design Patterns

CDP - Singleton import java.applet.AudioClip;

// This class used to avoid playing two audio clips at the same time.

// The class has only one instance accessed through its getInstance method.

// When you play through that object, it stops the last audio clip and starts the new one.

// If all audio clips are played through the AudioClipManager object,

// then there will never be more than one audio clip playing at the same time.

public class AudioClipManager implements AudioClip{

private static AudioClipManager myInstance

= new AudioClipManager();

private AudioClip prevClip; // previously requested audio clip

// Private constructor defined so compiler won't generate a default public constructor.

private AudioClipManager() { }

Page 73: Creational Design Patterns

CDP - Singleton

// Return a reference to the only instance of this class.

public static AudioClipManager getInstance() { return myInstance; } // getInstance()

// Start playing this audio clip. Each time method is called, clip is restarted from beginning.

public void play() { if (prevClip != null) prevClip.play(); } // play()

// Stop previously requested audio clip and play the given audio clip.

// @param clip the new audio clip to play.

public void play(AudioClip clip) {

if (prevClip != null)

prevClip.stop();

prevClip = clip;

clip.play();

} // play(AudioClip)

Page 74: Creational Design Patterns

CDP - Singleton // Starts playing this audio clip in a loop.

public void loop() {

if (prevClip != null) prevClip.loop(); } // loop()

// Stop previously requested audio clip and play the given audio clip in a loop.

// @param clip the new audio clip to play.

public void loop(AudioClip clip) {

if (prevClip != null) prevClip.stop();

prevClip = clip; clip.loop();

} // play(AudioClip)

// Stops playing this audio clip.

public void stop() { if (prevClip != null) prevClip.stop(); } // stop()

} // class AudioClipManager

Page 75: Creational Design Patterns

CDP - Singletonimport java.util.HashSet;

// This class has methods to ensure that an object is never garbage collected.

public class ObjectPreserver implements Runnable {

// This keeps this class and everything it references from being garbage collected

private static ObjectPreserver lifeLine = new ObjectPreserver();

// Since class won't be garbage collected, neither will HashSet or object it references.

private static HashSet protectedSet = new HashSet();

// Constructor.

private ObjectPreserver() { new Thread(this).start(); } // constructor()

public void run() { try { wait(); } catch (InterruptedException e) { } // try } // run()

// Garbage collection of objects passed prevented until sent to unpreserveObject method.

public static void preserveObject(Object o) { protectedSet.add(o); } // preserveObject()

// Objects passed to method lose protection preserveObject method gave from garbage

public static void unpreserveObject(Object o) {protectedSet.remove(o); } // unpreserveO..

} // class ObjectPreserver

Page 76: Creational Design Patterns

CDP - Object Pool

Synopsis:

Manages reuse of objects when a type of object is expensive to create or only a limited number of objects can be created.

Context:

You wish to limit access to a resource

Forces:

A program may not create more than a limited number of instances for a particular class

Page 77: Creational Design Patterns

Solution:

Create a reusable class to collaborate with other objects for a limited amount of time.

Create a reusable pool to manage reusable objects for use by client objects.

Consequences:

Requests may have to wait for an object to become unused.

CDP - Object Pool

Page 78: Creational Design Patterns

Allow DatabaseAccess

database access

Suppose you have a database systems that need to allow only a limited number of accesses to the database at one time.

CDP - Object Pool

database access requested

You must write a counting semaphore to protect this resource from having more than the limited access.

Page 79: Creational Design Patterns

CDP - Object Pool

Clientmanage objects

ReusablePool

uses

Reusable

Reusable Pool

Page 80: Creational Design Patterns

CDP - Object Pool// Public class used outside database access library to represent a database connection.

public class Connection {

private final static ConnectionImpl.ConnectionPool

connectionPool = ConnectionImpl.ConnectionPool.getInstance();

private String databaseName;

//...

// Send a request to the database and return the result.

Object sendRequest(Request request) {

Object result;

ConnectionImpl impl = connectionPool.acquireImpl(databaseName);

result = impl.sendRequest(request);

connectionPool.releaseImpl(impl);

return result;

} // sendRequest(Request)

} // class Connection

Page 81: Creational Design Patterns

CDP - Object Poolimport java.util.Hashtable;

import java.util.Vector;

// Instances of this class provide actual connections to a database.

class ConnectionImpl {

// Name of the datbase this object connected to.

private String dbName;

// Private Constructor

private ConnectionImpl(String dbName) {

this.dbName = dbName;

//...

} // constructor()

//...

// return the name of the database that this objects is connected to.

String getDatabaseName() { return dbName; } // getDatabaseName()

Page 82: Creational Design Patterns

CDP - Object Pool// Send a request to the database and return the result.

Object sendRequest(Request request) {

Object result = null;

//...

return result;

} // sendRequest(Request)

//...

static class ConnectionPool { // The one instance of this class

private static ConnectionPool thePool = new ConnectionPool();

// Hash table associates database names with corresponding Vector that contains

// a pool of connections for that database.

private Hashtable poolDictionary = new Hashtable();

// This constructor is private to prevent other classes from creating instances of this class.

private ConnectionPool() { }

Page 83: Creational Design Patterns

CDP - Object Pool// Return the one instance of this class.

public static ConnectionPool getInstance() { return thePool; } // getInstance()

/**

* Return a ConnectionImpl from appropriate pool or create one if the pool is empty.

* @param dbName Name of database that ConnectionImpl is to be supplied for.

*/

public synchronized ConnectionImpl acquireImpl(String dbName) {

Vector pool = (Vector)poolDictionary.get(dbName);

if (pool != null) {

int size = pool.size();

if (size > 0) return (ConnectionImpl)pool.remove(size-1);

} // if null

// No ConnectionImpl in pool, so create one.

return new ConnectionImpl(dbName);

} // acquireImpl(String)

Page 84: Creational Design Patterns

CDP - Object Pool /**

* Add a ConnectionImpl to the appropriate pool.

*/

public synchronized void releaseImpl(ConnectionImpl impl) {

String databaseName = impl.getDatabaseName();

Vector pool = (Vector)poolDictionary.get(databaseName);

if (pool == null) {

pool = new Vector();

poolDictionary.put(databaseName, pool);

} // if null

pool.addElement(impl);

} // releaseImpl(ConnectionImpl)

} // class ConnectionPool

} // class ConnectionImpl

Page 85: Creational Design Patterns

CDP - Object Pool/**

* Objects used to transmit requests to the database implment this

* interface.

*/

interface Request {

//...

} // interface Request