装饰器模式

装饰器模式

也叫包装模式,指在不改变原有对象的基础上,将功能附加到对象上,提供比继承更有弹性的替代方案

功能

  1. 扩展一个类的功能,增加一个类的职责
  2. 动态扩展一些职责,也可以撤销

示例装饰Logger输出json字符串

// 装饰器抽象类,必须实现被装饰的接口,同时生成构造方法,传入被装饰的对象
public abstract class LoggerDecorator implements Logger {

    protected Logger logger;

    // 重点
    public LoggerDecorator(Logger logger) {
        this.logger = logger;
    }
}
import com.alibaba.fastjson.JSONObject;
import org.slf4j.Logger;

// 具体装饰器类,完成装饰功能
public class JsonLogger extends LoggerDecorator{
    public JsonLogger(Logger logger) {
        super(logger);
    }

    @Override
    public void info(String s) {
        JSONObject jsonObject = newJson();
        jsonObject.put("message", s);
        logger.info(jsonObject.toString());
    }

    @Override
    public void error(String s) {
        JSONObject jsonObject = newJson();
        jsonObject.put("error", s);
        logger.error(jsonObject.toString());
    }

    public void error(Exception e){
        JSONObject jsonObject = newJson();
        jsonObject.put("error", e.getMessage());
        logger.error(jsonObject.toString());
    }

    private JSONObject newJson(){
        return new JSONObject();
    }
}
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
// 工具类,对生成装饰器类的封装
public class JsonLoggerFactory {
    public static JsonLogger getJsonLogger(Class clazz){
        Logger logger = LoggerFactory.getLogger(clazz);
        return new JsonLogger(logger);
    }
}
import org.slf4j.Logger;
// 测试代码
public class Test {
    private static final Logger logger = JsonLoggerFactory.getJsonLogger(Test.class);
    public static void main(String[] args) {
        logger.error("test json logger err");
        logger.info("test json logger");
    }
}

结果如下

[main] ERROR com.lovingmo.decorator.Test - {"error":"test json logger err"}
[main] INFO com.lovingmo.decorator.Test - {"message":"test json logger"}

源码中的使用

  1. 输入输出流
    InputStream in = new FileInputStream("");
    BufferedInputStream inputStream = new BufferedInputStream(in);
  1. spring事务中的:TransactionAwareCacheDecorator implements Cache

  2. mybaits中的Cache, LruCahe, FifoCache等等

优点

  1. 装饰器是对继承的有力补充,他比继承更加灵活,可以在不改变原有对象的基础上动态扩展对象功能,即插即用
  2. 通过使用不同的装饰器类和排列组合这些对象,可以实现不同的功能
  3. 完全符合开闭原则

缺点

  1. 会出现更多的代码,更多的类,显得更复杂
  2. 动态装饰时,多成装饰更加复杂

总结

  1. 装饰器模式也是一种特殊的静态代理
  2. 装饰器模式强调自身功能的透明扩展(用户可以控制是否装饰)
  3. 代理模式强调代理过程的控制
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容