Java设计模式-代理模式

栏目: Java · 发布时间: 5年前

内容简介:委托者: 实际服务提供者代理者: 中间商客户: 服务的消费者

代理模式

概述

委托者: 实际服务提供者

代理者: 中间商

客户: 服务的消费者

优缺点

优点:

  1. 隐匿委托者
  2. 客户和委托者实现解耦, 在不修改委托者的情况下可做额外操作.

分类

根据代理类在运行前是否存在,分为:

静态代理: 运行前已存在代理类

动态代理: 运行前未存在代理类

场景举例

厂家(Vendor)生产产品, 厂家可以直接销售给用户(Customer), 也可以通过代理商(Agent)销售给用户.代理商不直接囤货,有客户需求再让

厂家发货销售. 类似于微商.

Vendor -> Customer

有的地方只有一级代理, 直接面向用户:

Vendor -> Agent -> Customer

有的地方有一级代理商和二级代理商, 其中二级代理商直接面向用户, 一级代理商做厂家和二级代理商的中间媒介,根据实际需求做一些事情.

比如给二级代理商售前培训, 售后的结算等等.

Vendor -> Proxy -> Agent -> Customer

业务实现

销售接口:

public interface Sell {

    /**
     * 售卖
     */
    void sell();
}

生产者:

public class Vendor implements Sell {

    @Override
    public void sell() {
        System.out.println("Vendor sell.");
    }
}

直接销售代理:

public class BusinessAgent implements Sell {

    private Vendor vendor;

    public BusinessAgent(Vendor vendor) {
        this.vendor =vendor;
    }

    @Override
    public void sell() {
        System.out.println("BusinessAgent sell.");
        // 代理商只卖给学生, 即为在不修改委托的情况下增加额外操作.
        if (isStudent()) {
            vendor.sell();
        }
    }

    private boolean isStudent() {
        boolean isStudent = new Random().nextBoolean();
        System.out.println("isStudent:" + isStudent);
        return isStudent;
    }
}

动态代理拦截:

public class DynamicProxy implements InvocationHandler {

    //接口的实现类
    private Object object;

    public DynamicProxy(Object o) {
        this.object = o;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("=========给代理商培训==========");
        //实现类对象object调用方法method并传入参数args
        Object o = method.invoke(object, args);
        System.out.println("=========售后维护结算==========");
        return o;
    }
}

生成动态代理文件:

System.out.println("==========exe:dynamicProxy==========");
    //生成一个二级代理商
    BusinessAgent agent = new BusinessAgent(new Vendor());
    //根据实际需要生成一个一级代理
    DynamicProxy dynamicProxy = new DynamicProxy(agent);
    //生成动态代理文件
    System.getProperties().put("sun.misc.ProxyGenerator.saveGeneratedFiles","true");
    //获取Sell接口的实例
    Sell sell = (Sell) Proxy.newProxyInstance(Sell.class.getClassLoader(), new Class[]{Sell.class}, dynamicProxy);
    //售卖产品
    sell.sell();

动态代理类文件:

public final class $Proxy0 extends Proxy implements Sell {
    private static Method m1;
    private static Method m2;
    //Sell的的sell方法
    private static Method m3;
    private static Method m0;

    static {
            try {
                m1 = Class.forName("java.lang.Object").getMethod("equals", Class.forName("java.lang.Object"));
                m2 = Class.forName("java.lang.Object").getMethod("toString");

                //获取Sell 的 sell方法
                m3 = Class.forName("net.devwiki.pattern.proxy.Sell").getMethod("sell");
                m0 = Class.forName("java.lang.Object").getMethod("hashCode");
            } catch (NoSuchMethodException var2) {
                throw new NoSuchMethodError(var2.getMessage());
            } catch (ClassNotFoundException var3) {
                throw new NoClassDefFoundError(var3.getMessage());
            }
        }

    public $Proxy0(InvocationHandler var1) throws  {
        super(var1);
    }

    public final boolean equals(Object var1) throws  {
        try {
            return (Boolean)super.h.invoke(this, m1, new Object[]{var1});
        } catch (RuntimeException | Error var3) {
            throw var3;
        } catch (Throwable var4) {
            throw new UndeclaredThrowableException(var4);
        }
    }

    public final String toString() throws  {
        try {
            return (String)super.h.invoke(this, m2, (Object[])null);
        } catch (RuntimeException | Error var2) {
            throw var2;
        } catch (Throwable var3) {
            throw new UndeclaredThrowableException(var3);
        }
    }

    //覆写Sell类的sell方法
    public final void sell() throws  {
        try {
            // h为InvocationHandler的实例, 调用DynamicProxy的invoke方法
            //进而调用实现类的sell方法
            //如果外部传入的是Vendor则直接是调用Vendor的sell
            //如果外部传入的是BusinessAgent, 则中间添加学生过滤
            super.h.invoke(this, m3, (Object[])null);
        } catch (RuntimeException | Error var2) {
            throw var2;
        } catch (Throwable var3) {
            throw new UndeclaredThrowableException(var3);
        }
    }

    public final int hashCode() throws  {
        try {
            return (Integer)super.h.invoke(this, m0, (Object[])null);
        } catch (RuntimeException | Error var2) {
            throw var2;
        } catch (Throwable var3) {
            throw new UndeclaredThrowableException(var3);
        }
    }
}

代码位置: Dev-Wiki/DesignPattern


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

微机原理与接口技术

微机原理与接口技术

李文英、李勤、刘星、宋蕴新 / 清华大学出版社 / 2001-9 / 26.00元

《高等院校计算机应用技术规划教材•应用型教材系列•微机原理与接口技术》是“高职高专计算机系列教材”之一。全书包括微机原理、汇编语言、接口技术三部分内容。微机原理部分讲述了80x86的内部结构及工作原理、半导体存储器及其系统、微型机总线结构等。汇编语言部分讲述了指令系统、编程技巧。接口技术部分讲述了中断系统、中断控制器、并行接口、串行接口、DMA控制器、定时器,以及A/D、D/A转换器等常用芯片的硬......一起来看看 《微机原理与接口技术》 这本书的介绍吧!

CSS 压缩/解压工具
CSS 压缩/解压工具

在线压缩/解压 CSS 代码

RGB转16进制工具
RGB转16进制工具

RGB HEX 互转工具

图片转BASE64编码
图片转BASE64编码

在线图片转Base64编码工具