设计模式——代理模式(Proxy)(静态代理、动态代理)

代码:GitHub

代理设计模式(歌手+经纪人)

1. 通用Code

  • 工作内容的接口
/**
 * 工作内容的接口
 *
 * @author ALion
 * @version 2019/1/30 21:16
 */
public interface Work {

    /**
     * 商议
     */
    void confer();

    /**
     * 签合同
     */
    void signContract();

    /**
     * 唱歌
     */
    void sing();

    /**
     * 收钱
     */
    void collectMoney();

}
  • 歌手
/**
 * 歌手
 * <p>
 *     歌手主要是唱歌,其他交给经纪人来代理
 * </p>
 *
 * @author ALion
 * @version 2019/1/30 21:15
 */
public class Singer implements Work {

    @Override
    public void confer() {
        System.out.println("Singer.confer: 歌手商议");
    }

    public void signContract() {
        System.out.println("Singer.signContract: 歌手签合同");
    }

    @Override
    public void sing() {
        System.out.println("Singer.sing: 歌手唱歌");
    }

    @Override
    public void collectMoney() {
        System.out.println("Singer.collectMoney: 歌手收钱");
    }

}

2. 静态代理

2.0 UML结构图

静态代理UML结构图

2.1 Code

  • 经纪人(代理)
import com.skey.designpattern.proxy.Work;

/**
 * 经纪人
 * <p>
 *     经纪人负责来代理商议、签合同、收钱,唱歌交给歌手
 * </p>
 *
 * @author ALion
 * @version 2019/1/30 21:16
 */
public class Agent implements Work {

    private Work work;

    /**
     * 构造器
     * @param work 歌手
     */
    public Agent(Work work) {
        this.work = work;
    }

    @Override
    public void confer() {
        System.out.println("Agent.confer: 经纪人商议");
    }

    @Override
    public void signContract() {
        System.out.println("Agent.signContract: 经纪人签合同");
    }

    @Override
    public void sing() {
        // 可以在唱歌前后再做些操作
        // 唱歌交给歌手自己来
        work.sing();
    }

    @Override
    public void collectMoney() {
        System.out.println("Agent.collectMoney: 经纪人收钱");
    }
}

2.2 Test

  • 静态代理测试
import com.skey.designpattern.proxy.staticproxy.Agent;

/**
 * 静态代理测试
 *
 * @author ALion
 * @version 2019/1/30 21:26
 */
public class StaticProxyTest {

    public static void main(String[] args) {
        Singer singer = new Singer();
        Work work = new Agent(singer);
        work.confer();
        work.signContract();
        work.sing();
        work.collectMoney();
    }

}

3. 动态代理(JDK自带动态代理)

3.0 UML结构图

动态代理UML结构图

3.1 Code

/**
 * 功能处理
 *
 * @author ALion
 * @version 2019/1/30 21:42
 */
public class WorkHandler implements InvocationHandler {

    private Work work;

    /**
     * 构造器
     *
     * @param work 歌手
     */
    public WorkHandler(Work work) {
        this.work = work;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        Object obj = null;
        // AOP编程就是在此处实现对调用某个方法的前后调用其他方法
        if ("sing".equals(method.getName())) {
            System.out.println("WorkHandler.invoke: 代理商议");
            System.out.println("WorkHandler.invoke: 代理签合同");
            // 唱歌时,让歌手去做
            obj = method.invoke(work, args);
            System.out.println("WorkHandler.invoke: 代理收钱");
        }

        return obj;
    }

}

3.2 Test

import com.skey.designpattern.proxy.dynamicproxy.WorkHandler;

import java.lang.reflect.Proxy;

/**
 * 动态代理测试
 *
 * @author ALion
 * @version 2019/1/30 21:44
 */
public class DynamicProxyTest {

    public static void main(String[] args) {
        Singer singer = new Singer();

        WorkHandler handler = new WorkHandler(singer);
        Work proxy = (Work) Proxy.newProxyInstance(
                ClassLoader.getSystemClassLoader(),
                new Class[]{Work.class},
                handler);
        proxy.sing();
    }

}

4. 动态代理(字节码操作)

4.1 javaassist (暂无示例)

4.2 cglib + ASM

public class DynamicProxyCglibTest {

    public static void main(String[] args) {
        /*
        <!-- cglib的maven依赖 pom.xml -->
        <dependency>
            <groupId>cglib</groupId>
            <artifactId>cglib</artifactId>
            <version>2.2.2</version>
        </dependency>
         */

        // Singer是否实现接口无所谓
        Singer singer = new Singer();

        Singer proxySinger = (Singer) Enhancer.create(Singer.class, new MethodInterceptor() {
            @Override
            public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
                Object obj = null;
                if ("sing".equals(method.getName())) {
                    System.out.println("Enhancer.invoke: 代理商议");
                    System.out.println("Enhancer.invoke: 代理签合同");
                    // 唱歌时,让歌手去做
                    obj = method.invoke(singer, args);
                    System.out.println("Enhancer.invoke: 代理收钱");
                }

                return obj;
            }
        });

        proxySinger.sing();
    }

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值