[设计模式]代理模式、适配器模式与装饰器模式

这三种设计模式在代码形式上十分相似。但是为了解决不同的问题而提出的:

  • 代理模式
  • 代理模式在不改变原始接口的条件下,为原始类控制访问、新增一些业务无关的功能。
  • 适配器模式
  • 将不兼容的接口转换为可兼容的接口。(一种以修正为目的的设计模式)。
  • 装饰器模式
  • 装饰器模式是对原始类的功能进行增强,支持多个装饰类的嵌套增强。

代理模式

  • 基于接口,若被代理类有接口,那么通常我们的代理类会实现与之一样的接口,注入被代理类,并在实现时,对被代理类进行增强。
  • 基于继承,有些被代理类并没有接口,因此只能使用继承的方式进行扩展。

静态代理的问题: 当我们有非常多实现了不同接口的类需要被代理的时候,静态代理的方式就显得非常麻烦。我们需要给每个被代理类实现相同的代理逻辑,但代码大多数都是重复的,我们可以使用反射进行动态代理来解决这一问题。

动态代理Java实现

我们需要实现 InvocationHandler 接口。

private class DynamicProxyHandler implements InvocationHandler {
    private Object proxiedObject;
    public DynamicProxyHandler(Object proxiedObject) {
        this.proxiedObject = proxiedObject;
    }
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Th
        long startTimestamp = System.currentTimeMillis();
        Object result = method.invoke(proxiedObject, args);
        long endTimeStamp = System.currentTimeMillis();
        long responseTime = endTimeStamp - startTimestamp;
        String apiName = proxiedObject.getClass().getName() + ":" + method.getNam
        RequestInfo requestInfo = new RequestInfo(apiName, responseTime, startTim
        metricsCollector.recordRequest(requestInfo);
        return result;
    }
}

实现完成后,将这个实现,以及被代理类的类加载器、被代理类的接口一同传入 Proxy类的静态方法 newProxyinstance中,就可以动态的创建代理类了。

public static Object newProxyInstance(ClassLoader loader, Class[] interfaces, InvocationHandler h)

适配器模式

简单来说,就是定义一个适配器接口,并继承需要被适配的类,然后实现适配器接口的相应方法。在实现接口的方法时,我们只需要实现那些需要被改造的旧接口,对于符合要求的旧接口,可以继续沿用父类方法。(因此,如果需要适配的对象接口很多,并且和新接口定义大部分都相同,那么可以直接使用基于类的实现)

基于实现的方法,是将被适配的类注入进来,再进行相应改造的方式。相较基于类的方式,更灵活。如果新旧接口存在较多的不一致,推荐使用基于实现的方式,会更加灵活。

比如slf4j就是一套统一不同底层日志包的接口。此外,考虑到不同日志包的api存在的不同,slf4j还提供了相应的适配器,来统一api管理。

装饰器模式

Original: https://www.cnblogs.com/xy1997/p/16655751.html
Author: xingyuanyuan
Title: [设计模式]代理模式、适配器模式与装饰器模式

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/588069/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球