Presentation is loading. Please wait.

Presentation is loading. Please wait.

02 - Structural Design Patterns – 1 Moshe Fresko Bar-Ilan University תשס"ח 2008.

Similar presentations


Presentation on theme: "02 - Structural Design Patterns – 1 Moshe Fresko Bar-Ilan University תשס"ח 2008."— Presentation transcript:

1 02 - Structural Design Patterns – 1 Moshe Fresko Bar-Ilan University תשס"ח 2008

2 Structural Patterns Structural Patterns are concerned with how classes and objects are composed to form larger structures. Adapter: Makes an interface to conform to another. So it makes a uniform abstraction of different interfaces. Composite: Describes how to build class hierarchy made up of classes for two kinds of objects: primitive and composite. Proxy: Acts as a convenient surrogate or placeholder for another object Flyweight: Defines a structure for sharing objects Decorator: How to add responsibilities to objects dynamically. Façade: How to make a single object represent an entire subsystem Bridge: Separates an object's abstraction from its implementation so that you can vary them independently

3 Decorator Moshe Fresko Bar-Ilan University תשס"ו - 2005-2006 Design Patterns Course

4 Decorator Intent: Attach additional responsibilities to an object dynamically. Decorators provide a flexible alternative to sub-classing for extending functionality. Motivation: Sometimes we want to add responsibilities to individual objects not to an entire class. A GUI toolkit should let you add properties like borders or scrolling to any component An inflexible way of doing it is by inheritance. A more flexible way is to enclose the component in another object that adds the border. The enclosing object is called a decorator. The decorator conforms the interface of the component it decorates The decorator forwards requests to the component and may perform additional actions.

5 Decorator – Motivation

6

7 Decorator – Applicability Use Decorator To add responsibilities to individual objects dynamically and transparently. For responsibilities that can be withdrawn. When extension by sub-classing is impractical.

8 Decorator – Motivation We want to define an abstract Food class (or a Food Interface) to represent any food that is offered by a Pizza shop. Let’s look at the following design … interface Food { float getPrice() ; String getDescription() ; } class Pizza implements Food { float getPrice() { return 50 ; } String getDescription() { return “Regular Pizza” ; } } class PizzaWithOnion extends Pizza // Adds 5 shekels { float getPrice() { return super.getPrice()+5 ; } String getDescription() { return super.getDescription() + “ with Onion” ; } }

9 Decorator – Motivation class PizzaWithCorn extends Pizza {// Adds 7 shekels … } class PizzaWithOnionAndCorn extends Pizza {// Adds 12 shekels … } // Etc. … // In the program Food f = new PizzaWithOnionAndCorn() ; … System.out.println(“You bought : “+f.getDescription()) ; System.out.println(“Price in Shekels is : “+f.getPrice()) ; …

10 Decorator – Motivation Problems: 1. Many classes have to be defined… (For all the combinations) 2. What if Corn’s price will rise from 7 shekels to 8 shekel ? 3. What if we have another addition, let’s say “Tuna Fish” ?

11 Decorator – Motivation Alternative design with “Decorator” pattern interface Food { float getPrice() ; String getDescription() ; } class Pizza implements Food { float getPrice() { return 50 ; } String getDescription() { return “Regular Pizza” ; } } class Addition implements Food { Food f ; Addition(Food f) { this.f = f ; } float getPrice() { return f.getPrice() ; } String getDescription() { return f.getDescription() ; } }

12 Decorator – Motivation class PlusOnion extends Addition { PlusOnion(Food f) { super(f) ; } float getPrice() { return super.getPrice() + 5 ; } String getDescription() { return super.getDescription() + “, with Onion”); } } class PlusCorn extends Addition { PlusCorn(Food f) { super(f) ; } float getPrice() { return super.getPrice() + 7 ; } String getDescription() { return super.getDescription() + “, with Corn”); } } // Etc. … // In the program Food f = new PlusOnion(new PlusCorn(new Pizza())) ; … System.out.println(“You bought : “+f.getDescription()) ; System.out.println(“Price in Shekels is : “+f.getPrice()) ;

13 Decorator – Structure

14 Decorator - Participants Component Defines the interface for objects that can have responsibilities added to them dynamically. ConcreteComponent Defines an object to which additional responsibilities can be attached. Decorator Maintains a reference to a Component object and defines an interface that conforms to Component’s interface. ConcreteDecorator Adds responsibilities to the component.

15 Decorator – Consequences 1. More flexibility then static inheritance 2. Avoids feature-laden classes high up in the hierarchy 3. A decorator and its component are not identical 4. Lots of little objects

16 Decorator – Implementation 1. Interface conformance 2. Omitting the abstract Decorator class 3. Keeping Component class lightweight 4. Changing the skin of an object versus changing the guts (like Strategy).

17 Decorator Example – Java Streams InputStream FileInputStream : Reads from a file ByteArrayInputStream : Reads from a byte-array StringBufferInputStream : Reads from a String PipedInputStream : Reads from another output pipe SequenceInputStream : Reads from two or more “InputStreams” sequentially FilterInputStream : As a “DECORATOR” abstract class DataInputStream : To Read Primitive Data Types. readInt(), readByte() BufferedInputStream : Adds buffering LineNumberInputStream : Counts the number of lines PushbackInputStream : Can push-back a character OutputStream FileOutputStream ByteArrayOutputStream PipedOutputStream FilterOutputStream DataOutputStream PrintStream BufferedOutputStream

18 Decorator Example – Java Streams // As it is defined in Java public abstract class InputStream { //... public abstract int read() throws IOException; public int read(byte b[]) throws IOException { return read(b, 0, b.length); } public int read(byte b[], int off, int len) throws IOException { //... } //... public void close() throws IOException { } //... }

19 Decorator Example – Java Streams // As it is defined in Java public class FilterInputStream extends InputStream { protected InputStream in; protected FilterInputStream(InputStream in) { this.in = in; } public int read() throws IOException { return in.read(); } public int read(byte b[]) throws IOException { return read(b, 0, b.length); } public int read(byte b[], int off, int len) throws IOException { return in.read(b, off, len); } public void close() throws IOException { in.close(); } //... }

20 Decorator Example – Java Streams More possible examples: A stream ascii character counter: Counts how many ascii characters are read/written via the stream. Even can create histograms and statistics of the characters or character sequences. A filter for writing only letters and digits while dropping the other characters. Compression component that compresses the data according to any compression algorithm (like Lampell-Ziv)

21 Adapter Moshe Fresko Bar-Ilan University תשס"ו - 2005-2006 Design Patterns Course

22 Adapter Intent: Convert the interface of a class into another interface clients expect. Adapter lets classes work together that couldn’t otherwise because of incompatible interfaces. Motivation: Sometimes a toolkit class that’s designed for reuse isn’t reusable only because its interface doesn’t match the domain-specific interface an application requires. The interface of graphical objects is defined by an abstract class Shape We define LineShape and PolygonShape TextShape is relatively hard so we want to use an already existing class TextView. It is unpractical to take and change the source-code Using Adapter in one of two ways By inheriting Shape’s interface and TextView’s implementation By composing TextView’s instance within a TextShape

23 Adapter – Motivation

24 Adapter – Applicability Use the Adapter pattern when You want to use an existing class, and its interface does not match the one you need. You want to create a reusable class that cooperates with unrelated and unforeseen classes. (object adapter) You need to use several existing subclasses, but it is impractical to adapt their interface by sub-classing every one.

25 Adapter – Structure Class Adapter Object Adapter

26 Adapter – Participants Target defines the domain-specific interface that Client uses. Client collaborates with objects conforming by the Target interface Adaptee defines an existing interface that needs adapting Adapter adapts the interface of Adaptee to the Target interface

27 Adapter – Consequences Class Adapter Adapts Adaptee to Target by committing to a concrete Adaptee class. As a consequence, a class adapter won’t work when we want to adapt a class and all its subclasses. Lets Adapter override some of Adaptee’s behavior, since Adapter is a subclass of Adaptee. Introduces only one object, and no additional pointer indirection is needed to get to the Adaptee. Object Adapter Lets a single Adapter work with many Adaptees. Makes it harder to override Adaptee behavior.

28 Adapter – Consequences Other issues How much adapting does Adapter need to do? Pluggable Adapters Two-way adapters


Download ppt "02 - Structural Design Patterns – 1 Moshe Fresko Bar-Ilan University תשס"ח 2008."

Similar presentations


Ads by Google