unit 13 decorator

62
Unit 13 Decorator Summary prepared by Kirk Scott 1

Upload: verne

Post on 24-Feb-2016

24 views

Category:

Documents


0 download

DESCRIPTION

Unit 13 Decorator. Summary prepared by Kirk Scott. Design Patterns in Java Chapter 27 Decorator. Summary prepared by Kirk Scott. The Introduction Before the Introduction. Suppose you have a set of small functionalities where you would like to mix and match the functionalities together - PowerPoint PPT Presentation

TRANSCRIPT

Page 1: Unit 13 Decorator

1

Unit 13Decorator

Summary prepared by Kirk Scott

Page 2: Unit 13 Decorator

2

Design Patterns in JavaChapter 27Decorator

Summary prepared by Kirk Scott

Page 3: Unit 13 Decorator

3

The Introduction Before the Introduction

• Suppose you have a set of small functionalities where you would like to mix and match the functionalities together

• In other words, you would like to be able to create objects with these characteristics:

• Depending on the construction sequence, calling a given method on one object results in one subset of functionalities

• For a different construction sequence, calling the same method on a different object results in another subset of functionalities

Page 4: Unit 13 Decorator

4

• The book notes that in a certain sense, the previous description applies to the Interpreter design pattern

• It was possible to package up various different program behaviors in different objects and run the programs by calling the execute method

• For the decorator pattern, the functionalities do not typically rise to the level of complete little stand-alone programs

Page 5: Unit 13 Decorator

5

• Also, the construction sequence for the interpreter and decorator examples differs

• For the interpreter, individual command objects were created and then added to a composite

• For the decorator, functionalities will be bundled into an object by sequences of construction

• An object is wrapped in another object with a given functionality, which is wrapped in another, which has additional functionality, and so on

• In other words, it’s a kind of nesting of objects and functionalities

Page 6: Unit 13 Decorator

6

• Finally, in preview, note that this chapter uses streams and writers as the first example, and mathematical functions as the second

• This set of overheads will only cover the first example

• You are not responsible for any material on the use of the Decorator design pattern in order to implement mathematical functions

Page 7: Unit 13 Decorator

7

• Book material:• Extending a code base usually means adding

classes to a design or methods to classes• The Decorator design pattern supports

extension by allowing a program at run time to construct objects that can have varying behavior

Page 8: Unit 13 Decorator

8

• Book definition:• The intent of Decorator is to let you compose new

variations of an operation at runtime.• Comment mode on:• Notice that the Decorator design pattern is not related

to the Composite design pattern• The book is using the word compose to describe the

nested construction process that results in an object with a method that contains a composite of functionalities

Page 9: Unit 13 Decorator

9

A Classic Example: Streams and Writers

• The Java API includes a set of classes that are related in such a way that they illustrate the Decorator design pattern

• These are the stream and writer classes which are used for file I/O and other purposes

• Let a generic FileReader or FileWriter be constructed in a program

• It is connected to an external file

Page 10: Unit 13 Decorator

10

• It is possible to pass the generic reader or writer as a construction parameter when making a more specific kind of reader or writer

• The new reader or writer adds I/O functionalities that don’t exist in the generic reader or writer

• The book illustrates this idea in the code on the following overhead

Page 11: Unit 13 Decorator

11

• public class ShowDecorator• {• public static void main(String[] args) throws IOException• {• FileWriter file = new FileWriter("sample.txt");• BufferedWriter writer = new BufferedWriter(file);• writer.write("a small amount of sample text");• writer.newLine();• writer.close();• }• }

Page 12: Unit 13 Decorator

12

• The book gives the foregoing example simply to illustrate the process of construction

• It doesn’t comment specifically on the methods• It is worth noting that the FileWriter class and the

BufferedWriter classes both have various write() methods that take various sets of parameters

• The point is that calling write() on a BufferedWriter object may differ from calling write() on a FileWriter object

Page 13: Unit 13 Decorator

13

• As shown in the example program, the call to write() takes a simple String parameter

• It may be that such a write() method doesn’t exist in the FileWriter class

• It may also be that the way the write() method writes to the file differs

Page 14: Unit 13 Decorator

14

• The PrintWriter class may be a slightly better illustration

• An instance is constructed the same way as the book’s BufferedWriter example

• FileWriter file = new FileWriter("sample.txt");• BufferedWriter writer = new BufferedWriter(file);

• The PrintWriter class has additional methods besides write(), including print() and println()

Page 15: Unit 13 Decorator

15

• In other words, among the things you gain from creating a print writer is the ability to write text to a file using the same method calls that you use to put it on the screen

• Obviously, this differs somewhat from the first example

• You aren’t getting the same method name with different functionality

• You’re actually getting new method names with the desired functionality

Page 16: Unit 13 Decorator

16

• The book shows how this pattern, as given in the Java API, can be extended

• In other words, it’s possible for programmers to write file I/O classes that are based on the Decorator design pattern

• The book’s goal is to have a hierarchy of classes that make it possible to format text before writing it to a file

Page 17: Unit 13 Decorator

17

• The formatting will be simple things like making it upper case or lower case

• The book refers to these formatting classes as filter classes

• It begins the presentation of the topic with the UML diagram given on the next overhead

• This will require a little explanation, which is given afterwards

Page 18: Unit 13 Decorator

18

Page 19: Unit 13 Decorator

19

• What the book doesn’t make clear is that both the Writer and FilterWriter abstract classes already exist in the Java API

• In other words, in schematic form, the Decorator design pattern is already made available in them

• FilterWriter extends Writer, but the open headed arrow tells you that an instance of FilterWriter is constructed with an instance of Writer

• Construction with an input parameter like that tells you that composition of behavior is at work

Page 20: Unit 13 Decorator

20

• The Java API textual documentation for the FilterWriter class is given on the next overhead

• When you read this documentation you realize that the API is preparing you to apply the Decorator design pattern if you want to

• Subclasses of FilterWriter should override at least some of the methods and may add methods

• Of course, that’s generally what subclasses do• However, it describes the relationship between FileWriter

and PrintWriter or BufferedWriter used above to illustrate the Decorator design pattern

Page 21: Unit 13 Decorator

21

Java API Documentation of the Class FilterWriter

• Abstract class for writing filtered character streams.

• The abstract class FilterWriter itself provides default methods that pass all requests to the contained stream.

• Subclasses of FilterWriter should override some of these methods and may also provide additional methods and fields.

Page 22: Unit 13 Decorator

22

• At the bottom of the previous UML diagram the OozinozFilter abstract class appeared

• It is this class and its subclasses where the work is going to be done

• The expanded UML diagram given on the next overhead shows all of the decorator classes that will be added to the overall design

Page 23: Unit 13 Decorator

23

Page 24: Unit 13 Decorator

24

• Note that each decorator will be constructed by passing in a writer

• It is a minor pictorial detail that the open arrowhead is now shown going between OozinozFilter and Writer instead of between FilterWriter and Writer

• It amounts to the same thing• Because of the inheritance hierarchy, the writer

passed in could be any one of the concrete classes lower down in the hierarchy

Page 25: Unit 13 Decorator

25

• Also notice that the subclasses may inherit or override the concrete write() methods in the OozinozFilter class

• However, they will have to provide implementations of the abstract write() method

• In fact, we’re not interested in overriding the concrete inherited methods

• The filter classes are going to do their work, and differ, according to the functionality of their implementation of the one, abstract write() method

Page 26: Unit 13 Decorator

26

• That method takes a single int at a time as its input parameter, representing a character

• The code for the OozinozFilter class is given on the next overhead

• It shows the implementations of the concrete methods and the definition of the abstract method

Page 27: Unit 13 Decorator

27

• public abstract class OozinozFilter extends FilterWriter • {• protected OozinozFilter(Writer out) • {• super(out);• }

• public void write(char cbuf[], int offset, int length) throws IOException • {• for (int i = 0; i < length; i++) • write(cbuf[offset + i]);• }

• public abstract void write(int c) throws IOException;

• public void write(String s, int offset, int length) throws IOException • {• write(s.toCharArray(), offset, length);• }• }

Page 28: Unit 13 Decorator

28

• In the previous code it is worth noting that the first concrete write() method depends on the abstract write() method for its implementation

• In file I/O there is no effective difference between the char and int types

Page 29: Unit 13 Decorator

29

• That means that this call in the concrete method:

• write(cbuf[offset + i]);• Uses this method:• public abstract void write(int c) throws IOException;

Page 30: Unit 13 Decorator

30

• The results of the second concrete method end up being the same

• It takes in a String, but when writing the string, it makes this call:

• write(s.toCharArray(), offset, length);

• In other words, it makes use of the other concrete method, which makes use of the abstract write() method

Page 31: Unit 13 Decorator

31

• The end result is this:• You can call any of the write() methods on an

instance of one of the filter classes• When you do so, whatever formatting was

implemented in the simple write() method will apply to all of them

• The code for the concrete, LowerCaseFilter class is shown on the next overhead

Page 32: Unit 13 Decorator

32

• public class LowerCaseFilter extends OozinozFilter • {• public LowerCaseFilter(Writer out) • {• super(out);• }

• public void write(int c) throws IOException • {• out.write(Character.toLowerCase((char) c));• }• }

Page 33: Unit 13 Decorator

33

• Calling a write() method on an instance of this class changes all text to lower case

• The implementation is not difficult• You don’t even have to do anything like add or

subtract Unicode values• You get to rely on a method that already exists

in the Character class

Page 34: Unit 13 Decorator

34

• On the next overhead an example program is given which uses the LowerCaseFilter

• This program doesn’t write to a file• Instead, it writes to the console, but this makes

no difference• The code illustrates nested construction, or

composition• It will output the String with the strange

capitalization in all small letters

Page 35: Unit 13 Decorator

35

• public class ShowLowerCase • {• public static void main(String[] args) throws IOException • {• Writer out = new ConsoleWriter();• out = new LowerCaseFilter(out);• out.write("This Text, notably ALL in LoWeR casE!");• out.close(); • }• }

Page 36: Unit 13 Decorator

36

• For better or worse, it has to be noted that the ConsoleWriter class used in the previous example is not a class in the Java API

• It doesn’t exist yet…• At the end of this section the book gives the

writing of such a class as a challenge

Page 37: Unit 13 Decorator

37

• The UpperCaseFilter class works the same was as the LowerCaseFilter class

• The only difference is a minor one in the implementation of the write() method, which is shown below

• public void write(int c) throws IOException • {• out.write(Character.toUpperCase((char) c));• }

Page 38: Unit 13 Decorator

38

• Next the book gives the TitleCaseFilter class• It capitalizes every word in a string which

follows white space• It would be considerably more complicated if

you tried to follow the real rules for capitalizing titles

• The code is given on the next overhead

Page 39: Unit 13 Decorator

39

• public class TitleCaseFilter extends OozinozFilter • {• boolean inWhite = true;

• public TitleCaseFilter(Writer out) • {• super(out);• }

• public void write(int c) throws IOException • {• out.write(inWhite ? Character.toUpperCase((char) c) :

Character.toLowerCase((char) c));• inWhite = Character.isWhitespace((char) c) || c == '"';• }• }

Page 40: Unit 13 Decorator

40

• Next the book gives the CommaListFilter class• It puts a comma and a space after every item

that’s written• It would be considerably more complicated if

you tried to insert commas between any words separated by white space in the String to be written

• The code is given on the next overhead

Page 41: Unit 13 Decorator

41

• public class CommaListFilter extends OozinozFilter • {• protected boolean needComma = false;

• public CommaListFilter(Writer writer) • {• super(writer);• }

• public void write(int c) throws IOException • {• if (needComma) • {• out.write(',');• out.write(' ');• }• out.write(c);• needComma = true;• }

• public void write(String s) throws IOException • {• if (needComma)• out.write(", ");

• out.write(s);• needComma = true;• }• }

Page 42: Unit 13 Decorator

42

• Keep in mind that the general plan of the filter classes is the same

• They take a parameter to be written and they “decorate” it or modify it in some way before writing it out

• The LowerCaseFilter, UpperCaseFilter, and TitleCaseFilter classes changed the characters

• The CommaListFilter added characters to the output

Page 43: Unit 13 Decorator

43

• Challenge 27.1• Write the code for RandomCaseFilter.java.

Page 44: Unit 13 Decorator

44

• Solution 27.1• One solution is:• [See the next overhead.]

Page 45: Unit 13 Decorator

45

• public class RandomCaseFilter extends OozinozFilter • {• public RandomCaseFilter(Writer out) • {• super(out);• }

• public void write(int c) throws IOException • {• out.write(Math.random() < .5 ?

Character.toLowerCase((char) c)• : Character.toUpperCase((char) c));• }• }

Page 46: Unit 13 Decorator

46

• Next the book mentions the WrapFilter class• It takes as an input parameter both a Writer

and a line length• It has the effect of eating up unnecessary

white space and adding enough at the beginning of a line of text to center it

• The book doesn’t bother to give the code because it is too long and complex

Page 47: Unit 13 Decorator

47

• Next the book gives another example program, ShowFilters, which illustrates how various different filter behaviors can be composed together with nested construction

• It shows nested construction three levels deep• The code for this example is given on the next

overhead

Page 48: Unit 13 Decorator

48

• public class ShowFilters • {• public static void main(String args[]) throws IOException • {• BufferedReader in = new BufferedReader(new FileReader(args[0]));• Writer out = new FileWriter(args[1]);• out = new WrapFilter(new BufferedWriter(out), 40);• out = new TitleCaseFilter(out);

• String line;• while ((line = in.readLine()) != null)• out.write(line + "\n");• • out.close();• in.close();• }• }

Page 49: Unit 13 Decorator

49

• The book shows sample input and output for the program

• I don’t see any reason to reproduce that here• Next the book turns to the question of output

to the screen instead of a file• This is tangential to the topic of the Decorator

design pattern

Page 50: Unit 13 Decorator

50

• However, it was used in one of the earlier examples

• So for the sake of completeness it will be covered

• The book shows where the ConsoleWriter class would fit into the hierarchy in the UML diagram given on the next overhead

Page 51: Unit 13 Decorator

51

Page 52: Unit 13 Decorator

52

• Challenge 27.2• Write the code for ConsoleWriter.java• Comment mode on:• You have seen programmer written code which served a

similar, but more general purpose before:• MyTerminalIO• The details of the code are not of particular interest• It is assumed that if it’s not totally transparent, it would

be easy enough to figure out how it worked by referring to the Java API

Page 53: Unit 13 Decorator

53

• Solution 27.2• One solution is:• [See the following overhead.]

Page 54: Unit 13 Decorator

54

• public class ConsoleWriter extends Writer • {• public void close() {}• public void flush() {}• • public void write(char[] buffer, int offset, int length) • {• for (int i = 0; i < length; i++) • System.out.print(buffer[offset + i]);• }• }

Page 55: Unit 13 Decorator

55

Summary

• The Decorator design pattern lets you mix together variations of an operation

• Input and output streams illustrate the pattern and illustrate the composition of behaviors with nested construction

• Not only is Java set up in this way, it allows you to create your own I/O (filter) classes that are based on the decoration idea

• The Decoration pattern can also be applied in other problem domains

Page 56: Unit 13 Decorator

56

The End

Page 57: Unit 13 Decorator

57

• The diagrams for the second half of the chapter are tipped in here for future reference

• You don’t have to worry about them because the second half wasn’t covered in class and you’re not responsible for it

Page 58: Unit 13 Decorator

58

Page 59: Unit 13 Decorator

59

Page 60: Unit 13 Decorator

60

Page 61: Unit 13 Decorator

61

Page 62: Unit 13 Decorator

62