装饰器模式
坦白的说装饰模式就是对一组对象的功能进行扩展。对现有对象添加新的功能,又不改变结构。 作为现有类的一个包装
意图:
动态的给对象增加一些额外的功能。装饰器模式比子类继承更灵活。
在不增加子类的情况下扩展类。
使用场景:动态增加一个类的功能,同时可以动态撤销
缺点:多层装饰比较复杂。
主要角色:
抽象接口、具体实现类、装饰类和具体装饰类
例如:
//基础接口
public interface Coder {
void code();
}
//具体实现类
public class Student implements Coder {
@Override
public void code() {
System.out.println("使用Java进行编程。。。");
}
}
//装饰类
public class JavaCoder implements Coder {
private Student student;
public JavaCoder(Student student) {
this.student = student;
}
@Override
public void code() {
student.code();
}
}
//具体装饰类
public class JavaWebCoder extends JavaCoder {
public JavaWebCoder(Student student) {
super(student);
}
@Override
public void code() {
super.code();
System.out.println("学习javaweb,然后进行编程");
}
}
public static void main(String[] args) {
Coder coder = new JavaWebCoder(new Student());
coder.code();
}
执行结果:
使用Java进行编程。。。
学习javaweb,然后进行编程
实际应用:
logger打印日志默认为字符串,现在有个功能,需要打印出json格式的日志。
使用装饰器模式:
装饰器类:
public class DecoratorLogger implements Logger {
public Logger logger;
public DecoratorLogger(Logger logger) {
this.logger = logger;
}
@Override
public void debug(String s, Object o) {
logger.debug(s,o);
}
@Override
public void info(String s) {
logger.info(s);
}
@Override
public void warn(String s) {
logger.warn(s);
}
@Override
public void error(String s) {
logger.error(s);
}
...
}
装饰器具体实现类:
public class JSONLogger extends DecoratorLogger {
public JSONLogger(Logger logger) {
super(logger);
}
@Override
public void debug(String s) {
JSONObject jsonObject = new JSONObject();
jsonObject.put("debug", s);
logger.debug(jsonObject.toString());
}
@Override
public void info(String s) {
JSONObject jsonObject = new JSONObject();
jsonObject.put("info", s);
logger.info(jsonObject.toString());
}
@Override
public void error(String s) {
JSONObject jsonObject = new JSONObject();
jsonObject.put("error", s);
logger.error(jsonObject.toString());
}
public static class JSONLoggerFactory {
public static JSONLogger getLogger(Class clazz) {
Logger logger = LoggerFactory.getLogger(clazz);
return new JSONLogger(logger);
}
}
}
private JSONLogger logger = JSONLogger.JSONLoggerFactory.getLogger(FileController.class);
@RequestMapping(value = "/upload2", method = RequestMethod.GET)
public String upload2() {
logger.info("file is uploading...");
return "success";
}
执行结果:
2018-02-24 11:00:05.850 INFO 11168 --- [nio-8081-exec-6] com.example.demo.web.FileController : {"info":"file is uploading..."}