java设计模式十一之代理模式

前言:

    代理模式可以对原来的类进行扩展,通过代理对象来访问目标对象。例如spring aop


怎么实现:

    抽象角色:真实对象与代理对象都需要实现的接口

    真实角色:继承抽象角色,要被代理的类

    代理类:扩展真实角色。


静态代理:
       
package com.xhx.designpattern;

/**
 * 抽象角色
 * 真实对象与代理对象都需要实现的接口
 */
public interface Subject {
    void sailBook(String bookName,Double money);
}
package com.xhx.designpattern;

/**
 * 真实角色
 */
public class RealSubject implements Subject {
    public void sailBook(String bookName,Double money) {
        System.out.println(bookName+"   "+money+"元");
    }
}

package com.xhx.designpattern;

import java.util.Objects;

/**
 * 代理角色,要接收真实的角色,
 * 然后再进行进一步封装
 */
public class ProxySubject implements Subject{

    private Subject subject;

    public void setSubject(Subject subject) {
        this.subject = subject;
    }

    public void sailBook(String bookName, Double money) {
        if(Objects.isNull(subject)){
            subject = new RealSubject();
        }
        System.out.println("打折");
        subject.sailBook(bookName,money);
        System.out.println("返优惠券");
    }
}

package com.xhx.designpattern;

/**
 * 自己实现代理
 * 静态代理
 */
public class App {
    public static void main(String[] args) {
        ProxySubject proxySubject = new ProxySubject();
        RealSubject realSubject = new RealSubject();
        proxySubject.setSubject(realSubject);
        proxySubject.sailBook("小金梅",20.00);
    }
}

运行结果:



动态代理:继承InvocationHandler,利用反射
package com.xhx.designpattern;

/**
 * 被代理类的抽象父类
 */
public interface Subject {
    void sailBoot(String bookName,Double money);
}

package com.xhx.designpattern;

/**
 * 被代理的类
 */
public class RealSubject implements Subject {
    public void sailBoot(String bookName, Double money) {
        System.out.println(bookName+" "+money+"元");
    }
}

package com.xhx.designpattern;

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

/**
 * 动态代理类必须实现这个接口  InvocationHandler
 */
public class MyHandler implements InvocationHandler {

    //被代理的对象
    private Subject subject;

    public void setSubject(Subject subject) {
        this.subject = subject;
    }

    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

        System.out.println(proxy.getClass().getName());

        System.out.println("打折");

        Object invoke = method.invoke(subject, args);

        System.out.println("赠代金券");
        return invoke;
    }
}
package com.xhx.designpattern;

import java.lang.reflect.Proxy;

/**
 * jdk动态代理
 */
public class App {

    public static void main(String[] args) {
        Subject subject = new RealSubject();
        System.out.println(subject.getClass().getName());
        MyHandler myHandler = new MyHandler();
        myHandler.setSubject(subject);

        //由哪个ClassLoader对象来对生成的代理对象进行加载
        //这个代理类要继承的接口
        //把代理类实例与handler关联,当动态代理类在调用方法的时候,会关联到这个对象上,invoke方法
        Subject proxySubject = (Subject)Proxy.newProxyInstance(RealSubject.class.getClassLoader(), subject.getClass().getInterfaces(), myHandler);
        proxySubject.sailBoot("小瓶梅",20.00);
        System.out.println(proxySubject.getClass().getName());

    }
}

运行结果:




我的git代码地址

猜你喜欢

转载自blog.csdn.net/u012326462/article/details/80785130