Java IO的装饰模式
我自己把装饰模式分为了几部分:
1.装饰品
装饰的动作(行为,方法)
2.被装饰的对象
被装饰的动作(行为,方法)
注:所有的装饰品和被装饰的对象要有一个共同的装饰接口或抽象类(用来建立装饰品和装饰对象的关联关系,并且可以保证装饰的顺序。),
装饰的动作和被装饰的动作是这个接口或者抽象类的不同实现,
装饰的动作中有对被装饰动作的调用。(这就要求装饰品中有一个被装饰的对象的属性,并且在调用动作之前初始化成功)
简单的例子:
使用PrintWriter将数组中的内容写入到test.txt文件中。其中PrintWriter、BufferedWriter是装饰器,FileWriter是被装饰对象,Writer是公共的父类,而Writer中的write方法就是用来实现装饰动作和被装饰动作的抽象方法(Writer#abstract public void write(char cbuf[], int off, int len) throws IOException;)。
1 public static void writeFileWithIO(int[] source){ 2 try (PrintWriter pw = new PrintWriter(new BufferedWriter(new FileWriter("test.txt")))) { 3 for (int o : source) { 4 pw.println(String.valueOf(o)); 5 } 6 } catch (IOException e) { 7 e.printStackTrace(); 8 } 9 }
PrintWriter的相关源码:
1 public class PrintWriter extends Writer { 2 3 /** 4 * The underlying character-output stream of this 5 * <code>PrintWriter</code>. 6 * 7 * @since 1.2 8 */ 9 protected Writer out; 10 11 /** 12 * Creates a new PrintWriter, without automatic line flushing. 13 * 14 * @param out A character-output stream 15 */ 16 public PrintWriter (Writer out) { 17 this(out, false); 18 } 19 20 public PrintWriter(Writer out, 21 boolean autoFlush) { 22 super(out); 23 this.out = out; 24 this.autoFlush = autoFlush; 25 lineSeparator = java.security.AccessController.doPrivileged( 26 new sun.security.action.GetPropertyAction("line.separator")); 27 } 28 29 30 /** 31 * Writes a string. This method cannot be inherited from the Writer class 32 * because it must suppress I/O exceptions. 33 * @param s String to be written 34 */ 35 public void write(String s) { 36 write(s, 0, s.length()); 37 } 38 39 public void write(String s, int off, int len) { 40 try { 41 synchronized (lock) { 42 ensureOpen(); 43 //这个out对象就是重点,之前和之后的代码都是“装饰品” 44 out.write(s, off, len); 45 } 46 } 47 catch (InterruptedIOException x) { 48 Thread.currentThread().interrupt(); 49 } 50 catch (IOException x) { 51 trouble = true; 52 } 53 } 54 }
BufferedWriter中的write方法代码:
1 public class BufferedWriter extends Writer { 2 3 private Writer out; 4 5 public void write(char cbuf[], int off, int len) throws IOException { 6 synchronized (lock) { 7 ensureOpen(); 8 if ((off < 0) || (off > cbuf.length) || (len < 0) || 9 ((off + len) > cbuf.length) || ((off + len) < 0)) { 10 throw new IndexOutOfBoundsException(); 11 } else if (len == 0) { 12 return; 13 } 14 15 if (len >= nChars) { 16 /* If the request length exceeds the size of the output buffer, 17 flush the buffer and then write the data directly. In this 18 way buffered streams will cascade harmlessly. */ 19 flushBuffer(); 20 //这个out对象也是一样 21 out.write(cbuf, off, len); 22 return; 23 } 24 25 int b = off, t = off + len; 26 while (b < t) { 27 int d = min(nChars - nextChar, t - b); 28 System.arraycopy(cbuf, b, cb, nextChar, d); 29 b += d; 30 nextChar += d; 31 if (nextChar >= nChars) 32 flushBuffer(); 33 } 34 } 35 } 36 37 }
FileWriter调用的是Writer的write方法。在这里就不贴出来了。如果有不准确的地方欢迎指出。
方法凌驾于努力之上,思维凌驾于方法之上,而二者必须基于努力才能体现自身价值。