• Java 之 设计模式——代理模式


    设计模式——代理模式

    一、概述

      1、代理模式

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

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

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

    二、实现方式

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

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

        实现步骤:

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

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

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

          (4)增强方法

           增强方法方式:

            ① 增强参数列表

            ② 增强返回值类型

            ③ 增强方法体执行逻辑

    三、案例

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

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

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

      

      在这里:

        北京联想公司=真实对象

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

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

      代码演示

      卖电脑的接口类

    1 public interface SaleComputer {
    2 
    3     public String sale(double money);
    4 
    5     public void show();
    6 }

      卖电脑真实类

     1 /**
     2  * 真实类
     3  */
     4 public class Lenovo implements SaleComputer {
     5     @Override
     6     public String sale(double money) {
     7 
     8         System.out.println("花了"+money+"元买了一台联想电脑...");
     9         return "联想电脑";
    10     }
    11 
    12     @Override
    13     public void show() {
    14         System.out.println("展示电脑....");
    15     }
    16 }

      代理对象类

     1 import java.lang.reflect.InvocationHandler;
     2 import java.lang.reflect.Method;
     3 import java.lang.reflect.Proxy;
     4 
     5 public class ProxyTest {
     6 
     7     public static void main(String[] args) {
     8         //1.创建真实对象
     9         Lenovo lenovo = new Lenovo();
    10         
    11         //2.动态代理增强lenovo对象
    12         /*
    13             三个参数:
    14                 1. 类加载器:真实对象.getClass().getClassLoader()
    15                 2. 接口数组:真实对象.getClass().getInterfaces()
    16                 3. 处理器:new InvocationHandler()
    17          */
    18         SaleComputer proxy_lenovo = (SaleComputer) Proxy.newProxyInstance(lenovo.getClass().getClassLoader(), lenovo.getClass().getInterfaces(), new InvocationHandler() {
    19 
    20             /*
    21                 代理逻辑编写的方法:代理对象调用的所有方法都会触发该方法执行
    22                     参数:
    23                         1. proxy:代理对象
    24                         2. method:代理对象调用的方法,被封装为的对象
    25                         3. args:代理对象调用的方法时,传递的实际参数
    26              */
    27             @Override
    28             public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    29                 /*System.out.println("该方法执行了....");
    30                 System.out.println(method.getName());
    31                 System.out.println(args[0]);
    32 
    33 
    34 
    35 
    36 */
    37                 //判断是否是sale方法
    38                 if(method.getName().equals("sale")){
    39                     //1.增强参数
    40                     double money = (double) args[0];
    41                     money = money * 0.85;
    42                     System.out.println("专车接你....");
    43                     //使用真实对象调用该方法
    44                     String obj = (String) method.invoke(lenovo, money);
    45                     System.out.println("免费送货...");
    46                     //2.增强返回值
    47                     return obj+"_鼠标垫";
    48                 }else{
    49                     Object obj = method.invoke(lenovo, args);
    50                     return obj;
    51                 }
    52 
    53 
    54 
    55             }
    56         });
    57 
    58         //3.调用方法
    59 
    60         String computer = proxy_lenovo.sale(8000);
    61         System.out.println(computer);
    62 
    63         proxy_lenovo.show();
    64     }
    65 }
  • 相关阅读:
    Redis五种数据结构解析
    深入理解JAVA线程池
    数据看板superset在Windows环境下安装
    为什么要用docker
    非常完善的两个微服务框架比较(SpringCloud与Dubbo)
    Nginx配置之负载均衡、限流、缓存、黑名单和灰度发布
    jq
    22 道高频 JavaScript 手写面试题及答案
    input 限制 中文输入
    vue(js)点击目标div以外区域将目标div隐藏
  • 原文地址:https://www.cnblogs.com/niujifei/p/11628090.html
Copyright © 2020-2023  润新知