1 / 62

Unit 13 Decorator

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

verne
Download Presentation

Unit 13 Decorator

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Unit 13Decorator Summary prepared by Kirk Scott

  2. Design Patterns in JavaChapter 27Decorator Summary prepared by Kirk Scott

  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

  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

  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

  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

  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

  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

  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

  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

  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(); • } • }

  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

  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

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

  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

  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

  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

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

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

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

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

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

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

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

  25. public abstract class OozinozFilter extends FilterWriter • { • protected OozinozFilter(Writer out) • { • super(out); • } • public void write(char cbuf[], int offset, int length) throws IOException • { • for (inti = 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); • } • }

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

  27. That means that this call in the concrete method: • write(cbuf[offset + i]); • Uses this method: • public abstract void write(int c) throws IOException;

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

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

  30. public class LowerCaseFilter extends OozinozFilter • { • public LowerCaseFilter(Writer out) • { • super(out); • } • public void write(int c) throws IOException • { • out.write(Character.toLowerCase((char) c)); • } • }

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

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

  33. 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 LoWeRcasE!"); • out.close(); • } • }

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

  35. 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)); • }

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

  37. public class TitleCaseFilter extends OozinozFilter • { • booleaninWhite = 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 == '"'; • } • }

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

  39. public class CommaListFilter extends OozinozFilter • { • protected booleanneedComma = 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; • } • }

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

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

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

  43. 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)); • } • }

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

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

  46. 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(); • } • }

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

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

More Related