COMP 121 Week 12: Decorator and Adapter Design Patterns.

26
COMP 121 COMP 121 Week 12: Decorator and Week 12: Decorator and Adapter Design Adapter Design Patterns Patterns

Transcript of COMP 121 Week 12: Decorator and Adapter Design Patterns.

Page 1: COMP 121 Week 12: Decorator and Adapter Design Patterns.

COMP 121COMP 121

Week 12: Decorator and Week 12: Decorator and Adapter Design PatternsAdapter Design Patterns

Page 2: COMP 121 Week 12: Decorator and Adapter Design Patterns.

Decorator Design PatternDecorator Design Pattern

Intent: augment objects with new responsibilitiesIntent: augment objects with new responsibilitiesUse when:Use when:– Extension by subclassing is impractical (want to add Extension by subclassing is impractical (want to add

responsibilities to individual objects, not an entire responsibilities to individual objects, not an entire class)class)

– Responsibilities can be withdrawnResponsibilities can be withdrawn

Decorator implements the same interface as the Decorator implements the same interface as the object it decoratesobject it decoratesA "shell" or "wrapper" around an objectA "shell" or "wrapper" around an object– Requests that come in to the decorator are "forwarded" Requests that come in to the decorator are "forwarded"

to the object it decoratesto the object it decorates

Page 3: COMP 121 Week 12: Decorator and Adapter Design Patterns.

Decorator Design Pattern (cont’d)Decorator Design Pattern (cont’d)

The key to a successful Decorator is to have a The key to a successful Decorator is to have a set of objects defined by an interfaceset of objects defined by an interface

Decorator implements the interface and takes an Decorator implements the interface and takes an object of that interface type as a parameter of its object of that interface type as a parameter of its constructor, which it saves internallyconstructor, which it saves internally

When a method is called on the decorator:When a method is called on the decorator:– May do some pre-processing before calling the same May do some pre-processing before calling the same

method on the decorated objectmethod on the decorated object– May do some post-processing on the results returned May do some post-processing on the results returned

from the same method in the decorated objectfrom the same method in the decorated object

Page 4: COMP 121 Week 12: Decorator and Adapter Design Patterns.

Why Use a Decorator PatternWhy Use a Decorator Pattern

More flexibility than inheritanceMore flexibility than inheritance– Responsibilities can be added or removed at runtime)Responsibilities can be added or removed at runtime)

Avoids feature-laded classes high up in the Avoids feature-laded classes high up in the hierarchyhierarchy

A "pay-as-you-go" approach to adding A "pay-as-you-go" approach to adding responsibilitiesresponsibilities– Can define a simple classCan define a simple class– Add functionality incrementally with decoratorsAdd functionality incrementally with decorators

Page 5: COMP 121 Week 12: Decorator and Adapter Design Patterns.

Decorator Example 1: SunglassesDecorator Example 1: Sunglasses

People “decorate” themselves in many different ways People “decorate” themselves in many different ways (for example clothing, makeup, jewelry, glasses)(for example clothing, makeup, jewelry, glasses)Sunglasses intercept incoming light and provide modified Sunglasses intercept incoming light and provide modified light to the eyeslight to the eyes– The eyes still get basically the same type of input (stream of light The eyes still get basically the same type of input (stream of light

into the eyes)into the eyes)– Input (light) is transformed by the sunglasses, but is still a form Input (light) is transformed by the sunglasses, but is still a form

of light (not converted into sound or smell)of light (not converted into sound or smell)

Eyes take in light whether or not the decorator (pair of Eyes take in light whether or not the decorator (pair of sunglasses) is presentsunglasses) is present– This “transparent” property of Decorator is what allows This “transparent” property of Decorator is what allows

Decorators to be chained togetherDecorators to be chained together– Person may wear contact lenses AND sunglassesPerson may wear contact lenses AND sunglasses

Page 6: COMP 121 Week 12: Decorator and Adapter Design Patterns.

Decorator Example 2: Audio Decorator Example 2: Audio Enhancers/FiltersEnhancers/Filters

Electronic devices or software can be used to Electronic devices or software can be used to enhance, morph, or disguise your voiceenhance, morph, or disguise your voice– Change vocal pitch and timbre or apply other effects Change vocal pitch and timbre or apply other effects

such as volume or vibratosuch as volume or vibrato

Filter changes the audio streamFilter changes the audio stream– Input is an audio streamInput is an audio stream– Output is an audio streamOutput is an audio stream

Audio may be passed through a series of filters Audio may be passed through a series of filters to get the sound qualities desiredto get the sound qualities desired– Chain of decoratorsChain of decorators

Used with musical instruments, tooUsed with musical instruments, too

Page 7: COMP 121 Week 12: Decorator and Adapter Design Patterns.

Decorator Example 3: Java File I/ODecorator Example 3: Java File I/O

Basic I/O classes are InputStream, Basic I/O classes are InputStream, OutputStream, Reader and WriterOutputStream, Reader and WriterNeed to add behaviors to the stream to get the Need to add behaviors to the stream to get the desired resultsdesired results– BufferedInputStream adds buffering for performanceBufferedInputStream adds buffering for performance– DataInputStream adds input of primitive data typesDataInputStream adds input of primitive data types

FileInputStream in = new FileInputStream("test.dat"); BufferedInputStream bin = new BufferedInputStream(in);DataInputStream dbin = new DataInputStream(bin);

Page 8: COMP 121 Week 12: Decorator and Adapter Design Patterns.

Decorator Example 4: Unmodifiable Decorator Example 4: Unmodifiable CollectionCollection

List<Product> products = List<Product> products = newnew ArrayList<Product>(); ArrayList<Product>();

products.add(products.add(newnew Product("Book")); Product("Book"));products.add(products.add(newnew Product("Game")); Product("Game"));

Collection<Product> readOnlyProducts = Collection<Product> readOnlyProducts = newnew UnmodifiableCollection<Product>(products); UnmodifiableCollection<Product>(products);

Product p = readOnlyProducts.get(1); // returns GameProduct p = readOnlyProducts.get(1); // returns GamereadOnlyProducts.add(readOnlyProducts.add(newnew Product(...)); // Throws exception Product(...)); // Throws exception

products.add(products.add(newnew Product("Puzzle")); Product("Puzzle"));

intint numProducts = readOnlyProducts.size(); // returns 3 numProducts = readOnlyProducts.size(); // returns 3

Page 9: COMP 121 Week 12: Decorator and Adapter Design Patterns.

publicpublic classclass CollectionDecorator<E> CollectionDecorator<E> implementsimplements Collection<E> { Collection<E> {

protectedprotected Collection<E> coll; Collection<E> coll;

publicpublic CollectionDecorator(Collection<E> c) { CollectionDecorator(Collection<E> c) { coll = c;coll = c; }}

publicpublic booleanboolean add(E obj) { add(E obj) { returnreturn coll.add(obj); coll.add(obj); }}

publicpublic intint size() { size() { returnreturn coll.size(); coll.size(); }}

// Other methods similar// Other methods similar

}}

Page 10: COMP 121 Week 12: Decorator and Adapter Design Patterns.

publicpublic classclass IteratorDecorator<E> IteratorDecorator<E> implementsimplements Iterator<E> { Iterator<E> {

protectedprotected Iterator<E> iter; Iterator<E> iter;

publicpublic IteratorDecorator(Iterator<E> it) { IteratorDecorator(Iterator<E> it) { iter = it;iter = it; }}

publicpublic booleanboolean hasNext() { hasNext() { returnreturn iter.hasNext(); iter.hasNext(); }}

publicpublic E next() { E next() { returnreturn iter.next(); iter.next(); }}

publicpublic voidvoid remove() { remove() { iter.remove(); iter.remove(); }}}}

Page 11: COMP 121 Week 12: Decorator and Adapter Design Patterns.

publicpublic classclass UnmodifiableCollection<E> UnmodifiableCollection<E> extendsextends CollectionDecorator<E> { CollectionDecorator<E> {

publicpublic UnmodifiableCollection(Collection<E> coll) { UnmodifiableCollection(Collection<E> coll) {

supersuper(coll);(coll); }}

publicpublic booleanboolean add(E obj) { add(E obj) {

throwthrow newnew UnsupportedOperationException("add not supported"); UnsupportedOperationException("add not supported"); }}

// Similar implementation for all methods that would change contents// Similar implementation for all methods that would change contents publicpublic Iterator<E> iterator() { Iterator<E> iterator() {

returnreturn newnew UnmodifiableIteratorUnmodifiableIterator<E>(coll.iterator());<E>(coll.iterator()); }}

}}

Page 12: COMP 121 Week 12: Decorator and Adapter Design Patterns.

publicpublic classclass UnmodifiableIterator<E> UnmodifiableIterator<E> extendsextends IteratorDecorator<E> { IteratorDecorator<E> {

publicpublic UnmodifiableIterator(Iterator<E> iter) { UnmodifiableIterator(Iterator<E> iter) {

supersuper(iter);(iter); }}

@Override@Override publicpublic voidvoid remove() { remove() {

throwthrow newnew UnsupportedOperationException("remove not UnsupportedOperationException("remove not supported");supported");

}}}}

Page 13: COMP 121 Week 12: Decorator and Adapter Design Patterns.

Question:Question:

How does the Decorator design pattern How does the Decorator design pattern differ from the Strategy design pattern?differ from the Strategy design pattern?

Page 14: COMP 121 Week 12: Decorator and Adapter Design Patterns.

Answer:Answer:

The Decorator pattern changes the “skin” of an The Decorator pattern changes the “skin” of an objectobject– The decorator is a wrapper or outer layer that The decorator is a wrapper or outer layer that

changes the behavior of an objectchanges the behavior of an object– The object doesn’t know about its decoratorsThe object doesn’t know about its decorators

The Strategy pattern changes the “guts”The Strategy pattern changes the “guts”– The strategy is changed by using a different strategy The strategy is changed by using a different strategy

object that alters or extends the behavior of an objectobject that alters or extends the behavior of an object– The object knows about the available strategiesThe object knows about the available strategies

Page 15: COMP 121 Week 12: Decorator and Adapter Design Patterns.

Adapter Design PatternAdapter Design Pattern

Intent:Intent:– Convert the interface of a class into another interface that the Convert the interface of a class into another interface that the

clients expectclients expect– Lets classes work together that otherwise couldn't because of Lets classes work together that otherwise couldn't because of

incompatible interfacesincompatible interfaces

Use when:Use when:– You want to use an existing class and its interface doesn't match You want to use an existing class and its interface doesn't match

the one you needthe one you need– You want to create a reusable class that cooperates with You want to create a reusable class that cooperates with

unrelated or unforeseen classes (classes that don't have unrelated or unforeseen classes (classes that don't have compatible interfaces)compatible interfaces)

Another type of “shell” or “wrapper” around an objectAnother type of “shell” or “wrapper” around an object– Requests that come in to the adapter are forwarded to the object Requests that come in to the adapter are forwarded to the object

being adapted, but the actual method being called is differentbeing adapted, but the actual method being called is different

Page 16: COMP 121 Week 12: Decorator and Adapter Design Patterns.

Adapter Example 1: Socket WrenchAdapter Example 1: Socket Wrench

A socket attaches to a ratchet, provided A socket attaches to a ratchet, provided that the size of the drive is the samethat the size of the drive is the sameTypical drive sizes in the United States are Typical drive sizes in the United States are 1/2" and 1/4“1/2" and 1/4“– A 1/2" drive ratchet will not fit into a 1/4" drive A 1/2" drive ratchet will not fit into a 1/4" drive

socket unless an adapter is usedsocket unless an adapter is used– A 1/2" to 1/4" adapter has a 1/2" female A 1/2" to 1/4" adapter has a 1/2" female

connection to fit on the 1/2" drive ratchet, and connection to fit on the 1/2" drive ratchet, and a 1/4" male connection to fit in the 1/4" drive a 1/4" male connection to fit in the 1/4" drive socketsocket

Page 17: COMP 121 Week 12: Decorator and Adapter Design Patterns.

Adapter Example 2: Travel Adapter Adapter Example 2: Travel Adapter KitsKits

In different parts of the world, different In different parts of the world, different wattages and outlet types make it wattages and outlet types make it impossible to use personal appliances impossible to use personal appliances (shavers, hair dryers, etc.) without (shavers, hair dryers, etc.) without modificationmodificationA travel adapter kit allows you to:A travel adapter kit allows you to:– Plug your appliance into a converter to Plug your appliance into a converter to

convert the wattageconvert the wattage– Plug the converter into the wall outlet by Plug the converter into the wall outlet by

adapting the plug typeadapting the plug type

Page 18: COMP 121 Week 12: Decorator and Adapter Design Patterns.

Adapter Example 3: Replacing Adapter Example 3: Replacing Legacy or 3rd Party SoftwareLegacy or 3rd Party Software

The adapter pattern is commonly used in The adapter pattern is commonly used in applications where some third party software is applications where some third party software is being replaced with some other softwarebeing replaced with some other softwareRather than rewrite the application to use the Rather than rewrite the application to use the new software interface, use an adapter to adapt new software interface, use an adapter to adapt the old interface to the new interface:the old interface to the new interface:– The application code calls the old interface, but is now The application code calls the old interface, but is now

making those requests via the adaptermaking those requests via the adapter– The adapter converts the requests to requests that The adapter converts the requests to requests that

are compatible with the new softwareare compatible with the new software– The adapter may do some pre- or post-processing in The adapter may do some pre- or post-processing in

order to adapt requestorder to adapt request

Page 19: COMP 121 Week 12: Decorator and Adapter Design Patterns.

Adapter Code Example Adapter Code Example publicpublic classclass Product { Product {

publicpublic Sku Sku getSkugetSku() {() { returnreturn sku; sku; }}

publicpublic voidvoid setSku(Sku sku) { setSku(Sku sku) { thisthis.sku = sku;.sku = sku; }}

publicpublic Money getCost() { Money getCost() { returnreturn cost; cost; }}

publicpublic voidvoid setCost(Money cost) { setCost(Money cost) { thisthis.cost = cost;.cost = cost; }}

publicpublic Money calculatePrice() { … } Money calculatePrice() { … }

publicpublic Money calculateMarkup() { … } Money calculateMarkup() { … }}}

Page 20: COMP 121 Week 12: Decorator and Adapter Design Patterns.

// We want to use this existing class in place of Product// We want to use this existing class in place of Productpublicpublic classclass InventoryItem { InventoryItem {

privateprivate String barCode; String barCode; privateprivate String itemName; String itemName; privateprivate doubledouble purchasePrice; purchasePrice; privateprivate doubledouble salePrice; salePrice;

publicpublic doubledouble sellsFor() { sellsFor() { returnreturn salesPrice; salesPrice; }}

publicpublic String getBarCode() { String getBarCode() { returnreturn barCode; barCode; }}

// More methods here// More methods here}}

Page 21: COMP 121 Week 12: Decorator and Adapter Design Patterns.

publicpublic interfaceinterface Product { Product { SkuSku getSku(); getSku(); voidvoid setSku(Sku sku); setSku(Sku sku);

Money getCost();Money getCost(); voidvoid setCost(Money cost); setCost(Money cost);

Money calculatePrice();Money calculatePrice(); Money calculateMarkup();Money calculateMarkup();

// More methods…// More methods…

}}

Page 22: COMP 121 Week 12: Decorator and Adapter Design Patterns.

publicpublic classclass InventoryItemToProductAdapter { InventoryItemToProductAdapter {

privateprivate InventoryItem item; InventoryItem item;

publicpublic InventoryItemToProductAdapter(InventoryItem i) { InventoryItemToProductAdapter(InventoryItem i) { item = i;item = i; }}

publicpublic voidvoid setCost(Money cost) { setCost(Money cost) { item.setPurchasePrice(cost);item.setPurchasePrice(cost); }}

publicpublic Money calculatePrice() { Money calculatePrice() { returnreturn newnew Money(item.sellsFor()); Money(item.sellsFor()); }}

// More methods…// More methods…}}

Page 23: COMP 121 Week 12: Decorator and Adapter Design Patterns.

/*/* * Now that we have the adapter, we can add InventoryItem* Now that we have the adapter, we can add InventoryItem * objects to a list of products and treat them like any* objects to a list of products and treat them like any * other product* other product */*/ List<Product> products = List<Product> products = newnew ArrayList<Product>(); ArrayList<Product>(); InventoryItem item = InventoryItem item = newnew InventoryItem(…); InventoryItem(…); products.add(products.add(newnew InventoryItemToProductAdapter(item)); InventoryItemToProductAdapter(item));

… …

// Having a half-off sale// Having a half-off sale forfor(Product product : products) {(Product product : products) { product.setCost(product.getCost().div(2));product.setCost(product.getCost().div(2)); }}

Page 24: COMP 121 Week 12: Decorator and Adapter Design Patterns.

Question?Question?

How does the Adapter design pattern How does the Adapter design pattern differ from the Decorator design pattern?differ from the Decorator design pattern?

Page 25: COMP 121 Week 12: Decorator and Adapter Design Patterns.

Answer:Answer:

The Decorator pattern only changes the The Decorator pattern only changes the object’s responsibilities, not its interfaceobject’s responsibilities, not its interface

The Adapter pattern changes the object’s The Adapter pattern changes the object’s interface, often without changing its interface, often without changing its responsibilitiesresponsibilities

Page 26: COMP 121 Week 12: Decorator and Adapter Design Patterns.

Questions?Questions?