1,装饰器模式利用包含代替继承,动态的给一个对象添加一些额外的功能。如下图UML,右侧采用装饰模式后实现。
2,装饰器角色描述:
-1,抽象构建角色(Component):接口,封装了将要实现的方法,如ILogger。
-2,具体构建角色(ConcreteComponent):多个类,实现了抽象构建接口。
-3,装饰角色(Decorator):抽象类,该类实现Component接口,同时引用对应接口的实例。
-4,具体装饰角色:对具体过程完成装饰。
3,具体代码如下:
package pattern.chp11.decorator.logger; /** * 类描述:日志接口 * * @author: Jing * @version $Id: Exp$ * * History: Jan 5, 2015 2:27:01 PM Jing Created. * */public interface ILogger { /** * * 方法说明:记录日志模式 * * Author: Jing * Create Date: Jan 5, 2015 2:27:27 PM * * @param msg * @return void */ void log(String msg);} package pattern.chp11.decorator.logger; import java.io.DataOutputStream;import java.io.FileOutputStream; /** * 类描述:文件LOG * * @author: Jing * @version $Id: Exp$ * * History: Jan 5, 2015 2:28:40 PM Jing Created. * */public class FileLogger implements ILogger { public void log(String msg) { DataOutputStream dos = null; try { dos = new DataOutputStream(new FileOutputStream("c:/log.txt", true)); dos.writeBytes(msg + "\r\n"); dos.flush(); dos.close(); } catch (Exception e) { e.printStackTrace(); } } }package pattern.chp11.decorator.logger; /** * 类描述:Console日志 * * @author: Jing * @version $Id: Exp$ * * History: Jan 5, 2015 2:27:54 PM Jing Created. * */public class ConsoleLog implements ILogger { public void log(String msg) { System.out.println("Console Log!"); } }package pattern.chp11.decorator.logger; /** * 类描述:装饰器 * * @author: Jing * @version $Id: Exp$ * * History: Jan 5, 2015 2:46:34 PM Jing Created. * */public abstract class Decorator implements ILogger { protected ILogger logger; public Decorator(ILogger logger) { this.logger = logger; }}package pattern.chp11.decorator.logger; /** * 类描述:信息大写日志 * * @author: Jing * @version $Id: Exp$ * * History: Jan 5, 2015 2:48:31 PM Jing Created. * */public class UpLogger extends Decorator { public UpLogger(ILogger logger) { super(logger); } public void log(String msg) { msg = msg.toUpperCase(); logger.log(msg); } }package pattern.chp11.decorator.logger; /** * 类描述:XML格式化数据 * * @author: Jing * @version $Id: Exp$ * * History: Jan 5, 2015 2:49:36 PM Jing Created. * */public class XMLLogger extends Decorator { public XMLLogger(ILogger logger) { super(logger); } public void log(String msg) { String s = "<msg>" + msg + "</msg>\r\n"; logger.log(s); } } package pattern.chp11.decorator.logger; /** * 类描述: * * @author: Jing * @version $Id: Exp$ * * History: Jan 5, 2015 2:51:22 PM Jing Created. * */public class MainTest { public static void main(String[] args) { ILogger fileLog = new FileLogger();//文件日志 XMLLogger log = new XMLLogger(fileLog); log.log("asdasdsad"); }}4,JDK中的装饰器。
JDK中装饰器使用最广的是IO输入输出流部分。查看对应源码。
-1,接口
java.lang.Readable
public int read(java.nio.CharBuffer cb) throws IOException;
-2,类 java.io.Reader
成员变量:protected Object lock
用来实现同步。初始化时,指向当前对象。
protected Reader() { this.lock = this; }-3,java.io.BufferedReader
成员变量:private Reader in;含有一个对Reader类的引用。
private char cb[]; 缓存区
方法:read
public int read() throws IOException { synchronized (lock) { ensureOpen(); for (;;) { if (nextChar >= nChars) { fill(); if (nextChar >= nChars) return -1; } if (skipLF) { skipLF = false; if (cb[nextChar] == '\n') { nextChar++; continue; } } return cb[nextChar++]; } } }
-4,java.io.LineNumberReader
继承BufferedReader
LineNumberReader extends BufferedReader
按行读取对应文件信息。
public int read() throws IOException { synchronized (lock) { int c = super.read(); if (skipLF) { if (c == '\n') c = super.read(); skipLF = false; } switch (c) { case '\r': skipLF = true; case '\n': /* Fall through */ lineNumber++; return '\n'; } return c; } }
-5,FileReader:实现对文件的读取
public class FileReader extends InputStreamReader/** * Creates a new <tt>FileReader</tt>, given the name of the file to read * from. * * @param fileName * the name of the file to read from * @exception FileNotFoundException * if the named file does not exist, is a directory rather * than a regular file, or for some other reason cannot be * opened for reading. */ public FileReader(String fileName) throws FileNotFoundException { super(new FileInputStream(fileName)); } /** * Creates a new <tt>FileReader</tt>, given the <tt>File</tt> to read * from. * * @param file * the <tt>File</tt> to read from * @exception FileNotFoundException * if the file does not exist, is a directory rather than a * regular file, or for some other reason cannot be opened * for reading. */ public FileReader(File file) throws FileNotFoundException { super(new FileInputStream(file)); } /** * Creates a new <tt>FileReader</tt>, given the <tt>FileDescriptor</tt> * to read from. * * @param fd * the FileDescriptor to read from */ public FileReader(FileDescriptor fd) { super(new FileInputStream(fd)); }可以看到IO流完全按照装饰模式来实现。