设计模式之结构型(7)

2023-09-10  本文已影响0人  宏势

结构型模式,共七种:适配器模式、装饰器模式、代理模式、外观模式、桥接模式、组合模式、享元模式。

一.适配器模式

1.一句话描述

2.类图/代码

image.png

Callable 目标接口, Runnable 被适配接口, RunnableAdapter适配类, 属于对象适配器

3.模式分类

根据适配类和被适配类的关系 分成两种

4.实战案例

5.总结

生活中的插座/转接线 也是非常典型的适配模式,

二、装饰器模式

1.一句话描述

2.类图

image.png

FilterInputStream 是装饰器, 以组合方式引用 Inpustream, 增强具体InputStream之类的功能

3. 实战案例

4.总结

1.动态地将功能附加到类上,无需修改原有类代码, 灵活性高
2.每个具体装饰器类专注于一个特定功能, 吻合单一职责原则
3.多个装饰器可以按需组合,实现复杂的功能组合

三、代理模式

1. 一句话描述

2.类图/代码/分类

代理分为静态代理动态代理

(1)静态代理

静态代理在编译时就将接口、实现类、代理类编译成class文件。


静态代理.png

(2)动态代理

动态代理是在运行时动态生成类字节码,并加载到 JVM 中的。

JDK动态代理:

RealSubject realSubject = new RealSubject();
Class c = realSubject.getClass();
Subject subject = (Subject) Proxy.newProxyInstance(c.getClassLoader(), c.getInterfaces(), new DynamicInvocationHandler(realSubject));
 subject.request();
class DynamicInvocationHandler implements InvocationHandler{
    private RealSubject realSubject;

    public DynamicInvocationHandler(RealSubject realSubject) {
        this.realSubject = realSubject;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("pre ...");
        Object object =  method.invoke(realSubject,args);
        System.out.println("after ....");
        return object;
    }
}

CGLIB动态代理:

        RealSubject realSubject = new RealSubject();
        Class c = realSubject.getClass();
        Enhancer enhancer = new Enhancer();
        // 设置类加载器
        enhancer.setClassLoader(c.getClassLoader());
        // 设置被代理类
        enhancer.setSuperclass(c);
        // 设置方法拦截器
        enhancer.setCallback(new CGLibMethodInterceptor());
        RealSubject proxy = (RealSubject) enhancer.create();
        proxy.request();
class CGLibMethodInterceptor implements MethodInterceptor{

    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        System.out.println("pre ...");
        Object object =  methodProxy.invokeSuper(o,objects);
        System.out.println("after ....1111");
        return object;
    }
}

3.实战案例

4.总结

动态代理有JDK 动态代理、CGLIB 动态代理
JDK动态代理只能代理实现了接口的类,CGLIB可以代理未实现任何接口的类(继承)
JDK动态代理直接写Class字节码,CGLIB代理使用ASM框架写Class字节码,相对复杂,生成代理类的效率比较低

四、外观模式

1. 一句话描述

2.类图/代码

image.png

3.实战案例

4.总结

1.简化接口,让接口更简单,引入外观类可以将子系统与客户端解耦
2.吻合迪米特法则
3.只需增加一个外观类,客户端只跟外观类交互,由外观类跟多个子系统类交互

五、桥接模式

1.一句话描述

2.类图

image.png

3.实战案例

4.总结

  1. 解决一个类存在两个独立变化的维度且两个维度都需要进行扩展(吻合开闭原则)
  2. 采用组合方式,更加灵活(吻合 合成/聚合复用原则)

六、组合模式

1.一句话描述

2.类图

image.png

3.实战案例

4.总结

经常跟迭代器模式在一起对比,其实代码结构类似,迭代器模式侧重的遍历这个行为,是行为模式,而组合模式关注重点是结构关系,即整理和部分

七、享元模式

1.一句话描述

2.类图

image.png

3.实战案例

       Integer i1 = 12;
       Integer i2 = new Integer(12);  //无法利用享元
        Integer i3 = Integer.valueOf(12);
        System.out.println(i==i1); //true
        System.out.println(i==i2); //false
        System.out.println(i==i3); //true

4.总结

享元模式VS单例模式,单例模式是为了保证对象全局唯一,享元模式对象复用,节省内存(多例)

上一篇下一篇

猜你喜欢

热点阅读