标签:
作用:
基于已经存在的功能提供增强功能。
将扩展的类作为新的类的构造函数参数传入,然后对这个类进行装饰处理。
为了让装饰者有被装饰的功能,需要存在继承关系。
简单的点讲就是为了扩展一个已定义好的类的功能,而不修改原来类的定义,原来的类仍然可以继续使用,现在定义一个新的类继承原来的类,同时在这个新的类中定义父类的成员变量,同时在构造方法中将外界的一个父类对象传给这个成员变量,然后既可以通过这个成员变量使用父类的方法,同时又可以增加新的方法实现对父类功能的扩充。例如IO流中很多类都采用了装饰模式,如BufferedReader类是装饰了Reader类,LineNumberReader类装饰了BufferedReader类。
示例1:
1 package com.qianfeng.decorator; 2 3 public class Demo12 { 4 5 public static void main(String[] args) { 6 Person p1 = new Zhansan(); 7 p1.show(); 8 9 Person p2 = new JeansDecorator(p1); 10 p2.show(); 11 12 Person p3 = new ShirtDecorator(p1); 13 p3.show(); 14 } 15 } 16 17 interface Person { 18 void show();// 显示一个人 19 } 20 21 abstract class DecoratorPerson implements Person { 22 private Person person; 23 24 DecoratorPerson(Person person) { 25 this.person = person; 26 } 27 } 28 29 class JeansDecorator extends DecoratorPerson { 30 31 JeansDecorator(Person person) { 32 super(person); 33 // TODO Auto-generated constructor stub 34 } 35 36 @Override 37 public void show() { 38 System.out.println("穿牛仔裤的person"); 39 40 } 41 } 42 43 class ShirtDecorator extends DecoratorPerson { 44 45 ShirtDecorator(Person person) { 46 super(person); 47 // TODO Auto-generated constructor stub 48 } 49 50 @Override 51 public void show() { 52 System.out.println("穿t恤的person"); 53 54 } 55 56 } 57 58 class Zhansan implements Person { 59 60 @Override 61 public void show() { 62 System.out.println("没有任何装饰的张三"); 63 64 } 65 66 }
示例2:
1 package com.qianfeng.decorator; 2 3 import java.io.FileReader; 4 import java.io.IOException; 5 import java.io.Reader; 6 7 public class Demo13 { 8 // LineNumberReader 装饰类,继承了BufferedReader 9 public static void main(String[] args) throws IOException { 10 FileReader fr = new FileReader("src/temp.txt"); 11 // LineNumberReader lnr = new LineNumberReader(fr); 12 // String line = null; 13 // lnr.setLineNumber(100); 14 // while ((line = lnr.readLine()) != null) { 15 // System.out.println(lnr.getLineNumber() + ":" + line); 16 // } 17 // lnr.close(); 18 19 MyLineNumberReader lnr = new MyLineNumberReader(fr); 20 String line = null; 21 // lnr.setLineNumber(1000); 22 while ((line = lnr.MyReadLine()) != null) { 23 System.out.println(lnr.getLineNumber() + ":" + line); 24 } 25 lnr.myClose(); 26 } 27 28 } 29 30 /* 31 * setLineNumber():设置起始行号 32 * 33 * myReadLine():每次读取一行 34 * 35 * getLineNumber():获得当前行号 36 */ 37 class MyBufferedReader { 38 private Reader r; // 真正读取功能的类 39 private char[] arr = new char[512];// 相当于缓冲区 40 private int index; // 数组下标 41 private int count; // 统计缓冲区中字符个数 42 43 public MyBufferedReader(Reader r) { 44 this.r = r; 45 } 46 47 // 实现一次读取一个的功能 48 public int myRead() throws IOException { 49 // 缓冲区中是否有数据 50 if (count == 0) { 51 // 从文件中读取数据到缓冲区,返回值读取的字符数 52 count = r.read(arr); 53 index = 0; // 下标为0 54 } 55 if (count < 0) // 文件末尾 56 return -1; 57 // 从缓冲区中读取一个字符 58 int num = arr[index]; 59 index++;// 下标+1 60 // 数量-1 61 count--; 62 return num; 63 64 } 65 66 // 一次读取一行 67 public String myReadLine() throws IOException { 68 StringBuilder sb = new StringBuilder(); 69 int num; 70 while ((num = myRead()) != -1) { 71 if (num == ‘\r‘) 72 continue; 73 else if (num == ‘\n‘) 74 return sb.toString(); 75 else 76 sb.append((char) num); 77 } 78 return null; 79 } 80 81 // 关闭流 82 public void myClose() throws IOException { 83 r.close(); 84 } 85 } 86 87 class MyLineNumberReader extends MyBufferedReader { 88 89 private int lineNumber; 90 91 public MyLineNumberReader(Reader r) { 92 super(r); 93 } 94 95 public void setLineNumber(int lineNumber) { 96 this.lineNumber = lineNumber; 97 } 98 99 public int getLineNumber() { 100 return this.lineNumber; 101 } 102 103 // 每次读取一行,行号+1 104 public String MyReadLine() throws IOException { 105 ++lineNumber; 106 return super.myReadLine(); 107 } 108 109 }
未完,待续。
标签:
原文地址:http://www.cnblogs.com/enjoy-coding/p/4803613.html