设计模式——代理模式

一、概述

  1、代理模式

    (1)真实对象:被代理的对象

    (2)代理对象:代理真实对象的

    (3)代理模式:代理对象代理真实对象,达到增强真实对象功能的目的

二、实现方式

  1、静态代理:有一个类文件描述代理模式

  2、动态代理:在内存中形成代理类(常用方式)

    实现步骤:

      (1)代理对象和真实对象实现相同的接口

      (2)代理对象 = Proxy.newProxyInstance();

      (3)使用代理对象调用方法

      (4)增强方法

       增强方法方式:

        ① 增强参数列表

        ② 增强返回值类型

        ③ 增强方法体执行逻辑

三、案例

  我们用买电脑这件事情来叙述一下动态代理:

  当我们想买一个联想电脑,而此时联想电脑公司在北京,我们在西安,如果买电脑还得去北京,比较浪费时间。

  这是在西安有一个联想代理商,我们可以从代理商这里预订一台电脑,而代理商去北京给我们取货。这样就形成了一种动态代理。

  

  在这里:

    北京联想公司=真实对象

    西安联想代理商=代理对象

  这里西安代理商可以把联想电脑销售到西安各地,扩大了销售市场,相当于增强了功能。

  代码演示

  卖电脑的接口类

 public interface SaleComputer {

     public String sale(double money);

     public void show();
}

  卖电脑真实类

 /**
* 真实类
*/
public class Lenovo implements SaleComputer {
@Override
public String sale(double money) { System.out.println("花了"+money+"元买了一台联想电脑...");
return "联想电脑";
} @Override
public void show() {
System.out.println("展示电脑....");
}
}

  代理对象类

 import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy; public class ProxyTest { public static void main(String[] args) {
//1.创建真实对象
Lenovo lenovo = new Lenovo(); //2.动态代理增强lenovo对象
/*
三个参数:
1. 类加载器:真实对象.getClass().getClassLoader()
2. 接口数组:真实对象.getClass().getInterfaces()
3. 处理器:new InvocationHandler()
*/
SaleComputer proxy_lenovo = (SaleComputer) Proxy.newProxyInstance(lenovo.getClass().getClassLoader(), lenovo.getClass().getInterfaces(), new InvocationHandler() { /*
代理逻辑编写的方法:代理对象调用的所有方法都会触发该方法执行
参数:
1. proxy:代理对象
2. method:代理对象调用的方法,被封装为的对象
3. args:代理对象调用的方法时,传递的实际参数
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
/*System.out.println("该方法执行了....");
System.out.println(method.getName());
System.out.println(args[0]); */
//判断是否是sale方法
if(method.getName().equals("sale")){
//1.增强参数
double money = (double) args[0];
money = money * 0.85;
System.out.println("专车接你....");
//使用真实对象调用该方法
String obj = (String) method.invoke(lenovo, money);
System.out.println("免费送货...");
//2.增强返回值
return obj+"_鼠标垫";
}else{
Object obj = method.invoke(lenovo, args);
return obj;
} }
}); //3.调用方法 String computer = proxy_lenovo.sale(8000);
System.out.println(computer); proxy_lenovo.show();
}
}

最新文章

  1. Lock、ReentrantLock、synchronized、ReentrantReadWriteLock使用
  2. Linux下的五个查找命令:grep、find、locate、whereis、which
  3. 奇怪的BUG
  4. MySQL 索引优化 btree hash rtree
  5. [BILL WEI]SQL 如何将查询到的列作为表名去查询数据
  6. 如何仿写thinkphp的C方法?
  7. 警告"Local declaration of 'XXX' hides instance variable"原因
  8. If the server requires more time, try increasing the timeout in the server editor
  9. H5微信通过百度地图API实现导航方式二
  10. 两点补充——CSS3新属性以及弹性布局
  11. 6月5 Smarty自定义函数
  12. dom操作------操作元素属性的若干方法
  13. MPP、SMP、NUMA概念介绍
  14. Android 开发工具类 31_WebService 获取手机号码归属地
  15. MYSQL系列之(二)
  16. robbe-1.2发布-支持最新版本的friso+WinNT下php各版本的dll
  17. PHP phpMyadmin数据库备份太大无法导入怎么
  18. php ul li 分类
  19. 全排列算法 --javascript 实现
  20. beetl模板的${!}用法

热门文章

  1. [转]Oracle左连接、右连接、全外连接以及(+)号用法
  2. WebRTC搭建前端视频聊天室——信令篇
  3. django文章对本项目有用的收集
  4. redis创建集群至少需要几个节点?至少需要几个master节点?
  5. Python - Django - form 组件动态从数据库取 choices 数据
  6. ng2 空标签
  7. RobotFrameWork中使用自定义关键字
  8. tomcat参数调整
  9. aspnetcore identity result.Succeeded SignInManager.IsSignedIn(User) false?
  10. status 和 typedef