设计模式(二)代理模式

示例源码:https://gitee.com/SIESteven/designpattern.git

一、什么是代理模式
为了对具体实现类的控制和管理的一种代码设计模型。

                                 
      如上图所示,这种设计模式通常由三方面组成:主题角色(多为接口),实现主题角色,代理角色。外部需要时,随时调用。

Subject:抽象接口。为RealSubject和Proxy提供接口。通过实现同一接口,Proxy在RealSubject出现的地方取代它。
RealSubject:具体的实现类
Proxy持有RealSubject的引用。在某些例子中,Proxy可以负责RealSubject的创建与销毁。客户与RealSubject的交互必须通过Proxy。
      代理模式又分为静态代理和动态代理。Java中动态代理还包括jkd和cglib两种实现方式
二、为什么提出代理模式
为了屏蔽外界对具体实现类的访问及管理。
三、如何实现
1、jdk动态代理
场景:甲方向乙方提出了需求。为了不让甲方控制、管理乙方的猿类,公司设置了产品经理来与甲方和猿类打交道。产品负责接收需求、简单评估需求、对猿类管理和访问。

             
如图所示。代理模式更注重过程。首先将实现需求这件事划分为两部分:甲方和乙方。
 
甲方:有某种要求
乙方:提供对要求的实现。包括猿、产品、老板。

乙方分为三种角色:老板、猿、产品。

老板:员工们都得给我好好干活

package proxy.myjdkproxy;
/**
 * 主题接口:老板
 */
public interface IBoss { 
    void dealDemands(); 
    void dealDemands(String demands);
}


猿:
明确贯彻老板实现甲方要求的理念
负责甲方要求的具体实现(搭建架构、写静态页)

package proxy.myjdkproxy;

/**
 * @auther: Steven
 * @created: 2018/2/7 22:35
 * Description:程序猿
 */
public class Coder implements IBoss {
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    private String name ="Steven";
    Coder(){
        System.out.println("我是猿:Steven ");
    }
    public void dealDemands() {
        System.out.println(" analysis demands ");
        System.out.println(" design ");
        System.out.println(" coding ");
        System.out.println(" test ");
        System.out.println(" commit code ");
    }
    public void dealDemands(String demands) {
        System.out.println(" analysis demands :"+demands);
        System.out.println(" design ");
        System.out.println(" coding ");
        System.out.println(" test ");
        System.out.println(" commit code ");
    }
}


产品(话事人):
明确贯彻老板实现甲方要求的理念
了解乙方小兵的信息
对小兵进行调度和访问

package proxy.myjdkproxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * @auther: Steven
 * @created: 2018/2/7 22:40
 * Description:产品经理
 */
public class Product implements InvocationHandler {
    // get coder
    private Coder coder;
    public boolean isHaveIdleCoder() {
        return haveIdleCoder;
    }

    public void setHaveIdleCoder(boolean haveIdleCoder) {
        this.haveIdleCoder = haveIdleCoder;
    }

    private boolean haveIdleCoder;

    public Object getInstance() {
        haveIdleCoder=true;
        System.out.println("客户您好,我是产品经理,正在核查是否有员工能处理您的问题");
        // 判断是否有空闲程序猿
        if (!haveIdleCoder) {
            System.out.println("现在没有人手,没法儿接需求。抱歉");
            return null;
        }
        System.out.println("哎呦,竟然有人闲着!");
        System.out.println("----内部沟通----交由某猿开始处理需求");
        this.coder = new Coder();
        Class cl = coder.getClass();
        // 获取新建coder的代理权
        Object proxy = Proxy.newProxyInstance(cl.getClassLoader(), cl.getInterfaces(), this);
        return proxy;
    }

    public Object getInstance(Coder coder) {
        this.coder = coder;
        Class cl = coder.getClass();
        return Proxy.newProxyInstance(cl.getClassLoader(), cl.getInterfaces(), this);
    }

    /**
     * 实现需求
     * @param proxy
     * @param method
     * @param args
     * @return
     * @throws Throwable
     */
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("---内部沟通----"+this.coder.getName()+"即将处理你的需求");
        Object result = method.invoke(this.coder, args);
        System.out.println("客户您好,您的需求已经完成了,请您验收");
        return result;
    }
}

最后需要说明的一点就是,在网上的某些例子中,把代理操作放到了甲方的代码中来进行代理操作,感觉那样做不太合适。因此采用了如上的方式。

四、总结

动态代理实际上是通过java反射技术对字节码进行重组,在功能代码执行之前、执行中、执行后可以进行操作。实践了AOP的思想。

转载于:https://my.oschina.net/u/3779495/blog/1620194

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值