什么是装饰器模式?
有些时候,我们希望为一个类添加一些功能,同时又不希望改变这个类原来的结构。
例如:我已经完成了一个日志的接口和它的各个实现类,但是这些类只有输出日志到不同地方的功能,LoggerFileSystem能将日志输出到文件系统(磁盘)中,LoggerCloud能将日志输出到云端的某个文件中。现在新需求来了,我想要在每条日志输出后顺带输出这条日志的时间,又不想去修改每个实现类的方法,这时候就能使用装饰者模式,为这个接口编写一个装饰类,修饰原来的日志输出。(这只是一个简单的例子,正常的日志输出一般都带有时间)
类图
具体实现
- Logger接口,定义写日志接口方法log()
/**
* @author zdxie
* @Date 上午 8:18 2017/9/23 0023
* @Description
*/
public interface Logger {
public void log(String message);
}
- 实现两个Logger实现类:LoggerFileSystem、LoggerCloud
/**
* @author zdxie
* @Date 上午 8:19 2017/9/23 0023
* @Description
*/
public class LoggerFileSystem implements Logger{
public void log(String message) {
System.out.println("Log into FileSystem:" + message);
}
}
/**
* @author zdxie
* @Date 上午 8:32 2017/9/23 0023
* @Description
*/
public class LoggerCloud implements Logger{
public void log(String message) {
System.out.println("Log into CloudSystem:" + message);
}
}
- 为Logger编写一个装饰器,在输入日之后输出当前时间,这个装饰类要实现Logger接口并且拥有一个Logger成员变量。
import java.util.Calendar;
/**
* @author zdxie
* @Date 上午 8:38 2017/9/23 0023
* @Description
*/
public class TimeLoggerDecorator implements Logger {
private Logger decoratorLogger;
public TimeLoggerDecorator(Logger decoratorLogger) {
this.decoratorLogger = decoratorLogger;
}
public void log(String message){
decoratorLogger.log(message);
logTime();
}
public void logTime(){
System.out.println(Calendar.getInstance().getTime());
}
}
测试输出
/**
* @author zdxie
* @Date 上午 8:40 2017/9/23 0023
* @Description
*/
public class LoggerTest {
public static void main(String[] args){
Logger logger1 = new TimeLoggerDecorator(new LoggerFileSystem());
logger1.log("登录系统...");
Logger logger2 = new TimeLoggerDecorator(new LoggerCloud());
logger1.log("登录系统...");
}
}
结果:
Log into FileSystem:登录系统...
Sat Sep 23 09:31:39 GMT+08:00 2017
Log into FileSystem:登录系统...
Sat Sep 23 09:31:39 GMT+08:00 2017