博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
《设计模式之禅》读书笔记--(7)代理模式
阅读量:4299 次
发布时间:2019-05-27

本文共 3683 字,大约阅读时间需要 12 分钟。

定义

代理模式为其他对象提供一种代理以控制对这个对象的访问。

类图

这里写图片描述

Subject 抽象主题角色

Subject抽象主题角色可以是抽象类也可以是接口,是一个最普通的业务类型定义,无特殊要求。

RealSubject 具体主题角色

RealSubject具体主题角色是业务逻辑的具体执行者。

Proxy 代理主题角色

Proxy代理主题角色负责对真实角色的应用,把所有抽象主题类定义的方法限制委托给真实主题角色实现,并且在真实主题角色处理完毕前后做预处理和善后处理工作。

实现

抽象主题类:

package com.sigalhu.proxypattern;public interface Subject {
//定义一个方法 public void request();}

真实主题类:

package com.sigalhu.proxypattern;public class RealSubject implements Subject {
//实现方法 @Override public void request() { //业务逻辑处理 }}

代理类:

package com.sigalhu.proxypattern;public class Proxy implements Subject {
//要代理哪个实现类 private Subject subject = null; //默认被代理者 public Proxy(){ this.subject = new Proxy(); } //通过构造函数传递代理者 public Proxy(Subject subject){ this.subject = subject; } //实现接口中定义的方法 @Override public void request() { this.before(); this.subject.request(); this.after(); } //预处理 private void before(){ //do something } //善后处理 private void after(){ //do something }}

优点

  • 职责清晰,真实的角色就是实现实际的业务逻辑,不用关心其他非本职责的事务,通过后期的代理完成一件事务,附带的结果就是编程简洁清晰;
  • 高扩展性,具体角色类的不管如何变化,只要它实现了接口,代理类就可以在不做任何修改的情况下使用;
  • 智能化,参考AOP

动态代理

动态代理是在实现阶段不用关心代理谁,而在运行阶段才指定代理哪一个对象。

这里写图片描述

动态代理实现代理的职责,业务逻辑Subject实现相关的逻辑功能,两者之间没有必然的相互耦合的关系。通知Advice从另一个切面切入,最终在高层模块也就是Client进行耦合,完成逻辑的封装任务。

抽象主题:

package com.sigalhu.proxypattern.dynamicproxy;public interface Subject {
//业务操作 public void doSomething(String str);}

真实主题:

package com.sigalhu.proxypattern.dynamicproxy;public class RealSubject implements Subject {
//业务操作 @Override public void doSomething(String str) { System.out.println("do something!-->" + str); }}

动态代理的Handler类:

package com.sigalhu.proxypattern.dynamicproxy;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Method;public class MyInvocationHandler implements InvocationHandler {
//被代理的对象 private Object target = null; //通过构造函数传递一个对象 public MyInvocationHandler(Object object){ this.target = object; } //代理方法 @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable{ //执行被代理的方法 return method.invoke(this.target, args); }}

动态代理类:

package com.sigalhu.proxypattern.dynamicproxy;import java.lang.reflect.InvocationHandler;import java.lang.reflect.Proxy;public class DynamicProxy
{
public static
T newProxyInstance(ClassLoader loader, Class
[] interfaces, InvocationHandler h){ //寻找JoinPoint连接点,AOP框架使用元数据定义 if(true){ //执行一个前置通知 (new BeforeAdvice()).exec(); } //执行目标,并返回结果 return (T) Proxy.newProxyInstance(loader,interfaces,h); }}

通知接口及实现:

package com.sigalhu.proxypattern.dynamicproxy;public interface IAdvice {
//通知只有一个方法,执行即可 public void exec();}
package com.sigalhu.proxypattern.dynamicproxy;public class BeforeAdvice implements IAdvice {
@Override public void exec() { System.out.println("前置通知!"); }}

场景类:

package com.sigalhu.proxypattern.dynamicproxy;import java.lang.reflect.InvocationHandler;public class Client {
public static void main(String[] args){ //定义一个主题 Subject subject = new RealSubject(); //定义一个Handler InvocationHandler handler = new MyInvocationHandler(subject); //定义主题的代理 Subject proxy = DynamicProxy.newProxyInstance( subject.getClass().getClassLoader(), subject.getClass().getInterfaces(), handler); //代理的行为 proxy.doSomething("Finish"); }}

源码:

你可能感兴趣的文章
Maven之阿里云镜像仓库配置
查看>>
Maven:mirror和repository 区别
查看>>
微服务网关 Spring Cloud Gateway
查看>>
SpringCloud Feign的使用方式(一)
查看>>
SpringCloud Feign的使用方式(二)
查看>>
关于Vue-cli+ElementUI项目 打包时排除Vue和ElementUI
查看>>
Vue 路由懒加载根据根路由合并chunk块
查看>>
vue中 不更新视图 四种解决方法
查看>>
MySQL 查看执行计划
查看>>
OpenGL ES 3.0(四)图元、VBO、VAO
查看>>
OpenGL ES 3.0(五)纹理
查看>>
OpenGL ES 3.0(八)实现带水印的相机预览功能
查看>>
OpenGL ES 3.0(九)实现美颜相机功能
查看>>
FFmpeg 的介绍与使用
查看>>
Android 虚拟机简单介绍——ART、Dalvik、启动流程分析
查看>>
原理性地理解 Java 泛型中的 extends、super 及 Kotlin 的协变、逆变
查看>>
FFmpeg 是如何实现多态的?
查看>>
FFmpeg 源码分析 - avcodec_send_packet 和 avcodec_receive_frame
查看>>
FFmpeg 新旧版本编码 API 的区别
查看>>
RecyclerView 源码深入解析——绘制流程、缓存机制、动画等
查看>>