代理模式(Proxy Pattern)(一)

本文详细介绍了代理模式,包括静态代理和动态代理。通过生活中的代理案例,阐述了代理模式的作用,如减少消费者成本、统一异常处理等。在Java中,静态代理通过接口实现功能增强,动态代理则利用JDK动态代理机制,在运行时动态生成代理类。动态代理允许在不修改原对象代码的情况下,扩展其功能。文章还深入探讨了动态代理的内部实现,包括Proxy类和InvocationHandler接口的应用。
摘要由CSDN通过智能技术生成

一 简介

1.1 生活当中的代理案例

  • 房屋中介代理

                房屋中介从 包租婆手中获取房源 卖给需要租房的人。

  • 商品代购(比如卖面膜)

                卖面膜的人 从厂家拿面膜 在朋友圈当中宣传 卖给熟人。

1.2 为什么要使用代理

  • 对于消费者而言只需要关注自己需要的商品,可以减少成本,不需要去寻找房源或者渠道,
  • 对于生产者(包租婆,厂家)只需要关注自己的产品,销售只需要让代理者去处理就好 关注自家
  • 对于代理者而言,可以增加类 扩展业务需求 比如收中介费

1.3代理模式在java当中的应用

  1. 统一了异常处理
  2. mybatis使用了代理
  3. spring aop实现了原理
  4. 日志框架

1.4概述

  1. 代理模式(Proxy Pattern):是23中设计模式中的一种,属于结构型的模式,指的是一个对象本身不做实际操作,而是通过其他对象来得到自己想要的结果。
  2. 意义:目标对象只需要关心自己的实现细节,通过代理对象来实现功能的增强,可以扩展目标对象的功能。
  3. 体现了非常重要的编程思想:不能随意修改源码,如果需要修改源码,通过修改代理的方式来实现功能的扩展。

1.5图示

 

 

 

 

  •  元素组成
  1. 接口:定义行为和规范
  2. 被代理类:是目标对象
  3. 代理类:做功能增强
  • 值得注意的点
  1.  用户只需要关注接口功能,而不在乎谁提供了功能。
  2. 接口真正实现这是目标对象,但是他不与用户接触,而是通过代理。
  3. 代理就是Proxy,由于它实现了接口,所以他能够与用户直接接触
  4. 用户调用Proxy的时候,Proxy内部调用了目标对象realSubject。所以Proxy是代理者,它可以增强RealSubject的功能操作。

二 静态代理

2.1 案例 

通过代理模式实现日志操作

2.2 实现案例

假设有一个大商场,商场有很多的柜台,有一个柜台卖茅台酒并且增加品尝和是否购买的需求。我们进行代码的模拟。

2.2.1 创建接口SellWine

首先得有一个接口,通用的接口是代理模式实现的基础。这个接口我们命名为 SellWine,代表卖酒这个行为。

public interface SellWine {
    void maiJiu();
}

2.2.2 创建目标对象MaiTaiJiu类

这个表示真正的对象,它实现了SellWine接口,卖酒的行为有了

(如果按照原始的方式就是在MaoTaiJiu这个对象的每一个方法当中分别添加pinchang()、isGouMai(),就很麻烦 代码冗余,并且如果想要添加增强类的话就需要这个真实对象的源码)

public class MaoTaiJiu implements SellWine{
    public void maiJiu() {
        System.out.println("我卖的是茅台酒!");
    }
    public void baoZhuang(){
        System.out.println("茅台酒的包装");
    }
    public void jiancha(){
        System.out.println("茅台酒日期的检查");
    }
}

2.2.3 创建Proxy GuiTai类

GuiTai就是一个Proxy对象 他有一个maiJiu()方法,不过在调用maiJiu()方法的时候有一些额外的行为比如说pinchang()、isGouMai()

public class GuiTai implements SellWine {
//代理的是MaoTaiJiu这个真实对象 类型固定了 无法代理别的品牌的酒
    private MaoTaiJiu maoTaiJiu;

    public void setMaoTaiJiu(MaoTaiJiu maoTaiJiu){
        this.maoTaiJiu=maoTaiJiu;
    }
  /*  public GuiTai(MaoTaiJiu maoTaiJiu){
        this.maoTaiJiu=maoTaiJiu;
    }*/


    public void maiJiu() {
        pinchang();
        maoTaiJiu.maiJiu();
        goumai(true);
    }

    public void pinchang(){
        System.out.println("客户您可以品尝!");
    }
    public void goumai(boolean isMai){
        if(isMai){
            System.out.println("购买结账!");
        }else{
            System.out.println("在考虑考虑!");
        }

    }
}

2.2.4 创建客户 Client类

public class Client {
    public static void main(String[] args) {
        //真实对象: 茅台酒
        MaoTaiJiu maoTaiJiu = new MaoTaiJiu();
        //代理对象:柜台
        GuiTai guiTai = new GuiTai();

        //通过代理角色 来实现真实对象茅台酒的卖酒
        //1 获取代理的是茅台酒的
        guiTai.setMaoTaiJiu(maoTaiJiu);
        guiTai.maiJiu();

    }
}

结果:

现在可以看到,代理模式可以在不修改被代理对象的基础上,通过扩展代理类,进行一些功能的附加与增强。值得注意的是,代理类和被代理类应该共同实现一个接口,或者是共同继承某个类。

上面介绍的是静态代理的内容,为什么叫做静态呢?因为它的类型是事先预定好

 

三 动态代理

上一节代码中 GuiTai类是代理,我们需要手动编写代码让 GuiTai 实现 SellWine 接口,而在动态代理中,我们可以让程序在运行的时候自动在内存中创建一个实现 SellWine 接口的代理,而不需要去定义 GuiTai 这个类。这就是它被称为动态的原因。

3.1 jdk动态代理

3.1.1 案例

3.1.1.1创
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值