首页 > 技术文章 > 设计模式(1-1)-代理模式

ukyu 2021-10-28 19:45 原文

几个月没写博客了。前些日子换了工作,把事情调整好了,又可以继续写博客了~

学习了下代理模式,本篇文章讲动态代理与静态代理模式怎么写,后续文章会讲动态代理(JDK动态代理)原理,讲讲怎么使用CGLIB实现没有接口的类的动态代理

一、代理在生活中的例子

代理, 代表授权方处理事务(wiki 的解释)。 举个例,顾客(client)想买一个u盘; 顾客想去西部数据工厂买一个u盘, 保安都直接把他拦住叫他去京东买; 没办法只能去被授权了的京东那去买,被可恶的中间商赚了差价。
虽然京东和西部数据都是卖u盘的,但是京东只是个代理商,最终需要的u盘还是要去西部数据进货,京东但是可以发优惠券在顾客买u盘前。
生活中的代理例子很多, 找中介租房子。自己不想做的事,可以交给代理方做,但是代理方也能力有限,最终的事还是需要交给本人去做。

代理模式有啥用?

  • 方法增强, 代理方不仅仅是卖u盘了,还可以发放优惠券,赚取差价
  • 控制访问,顾客去找西部数据工厂买个u盘,保安直接把他拦住了

二、 静态代理模式实现

下面我们先看看静态代理在Java中的实现

以买卖u盘为例子,

步骤一,定义一个接口(serviceInterface), 定义厂家与代理商的共同目标(卖u盘)

public interface UpanSell {

    float sell(int amount);
}

步骤二,创建厂家类(serive),实现步骤一定义的接口

public class WesternDigitalUpanFactory implements UpanSell {

    @Override
    public float sell(int amount) {

        float price = 85.0f * amount;

        System.out.println("------西部数据卖出" + amount + "个u盘, 价格: " + price);

        return price;
    }
}

步骤三,创建一个商家类(proxy),实现相同的接口

public class jd implements UpanSell {

    private final UpanSell upanSell = new WesternDigitalUpanFactory();

    @Override
    public float sell(int amount) {

        float price = upanSell.sell(amount);

        // -------增强功能 ↓↓↓↓↓↓↓↓↓↓

        // 中间商赚差价
        price += 25.f * amount;

        System.out.println("------京东卖出" + amount + "个u盘, 价格: " + price);
        System.out.println("------给你一个优惠券, 0.01分");

        return price;
    }
}

步骤四, 创建一个客户端(client)调用商家买U盘

public class Shop {
    public static void main(String[] args) {
        UpanSell upanSell = new jd();

        upanSell.sell(2);
    }
}

输出结果

------西部数据卖出2个u盘, 价格: 170.0
------京东卖出2个u盘, 价格: 220.0
------给你一个优惠券, 0.01分

上面的代理类(jd), 做了两件事,1. 中间商加了价格 2. 给了我们一张优惠券

我们能看到静态代理的实现还是挺简单的,也是多态的一个运用,我们是由商家类调用到的厂家类。
简单是简单,但是

  1. 如果多一个商家,比如淘宝,也要卖了,是不是需要多一个代理类。
  2. 如果serviceInterface,是不是厂家类与商家类都要修改。

那么,我们来看看动态代理是怎么把这些缺点规避掉的

运用JDK实现动态代理

推荐阅读