装饰器模式
坦白的说装饰模式就是对一组对象的功能进行扩展。对现有对象添加新的功能,又不改变结构。 作为现有类的一个包装
意图:
动态的给对象增加一些额外的功能。装饰器模式比子类继承更灵活。
在不增加子类的情况下扩展类。
使用场景:动态增加一个类的功能,同时可以动态撤销
缺点:多层装饰比较复杂。
主要角色:
抽象接口、具体实现类、装饰类和具体装饰类
例如:
//基础接口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..."}