• 代理模式


    代理模式

    • 一个类拥有另一个类的功能。

    介绍

    意图:

    • 为类提供一种代理以控制对这个类的访问

    使用场景:

    • 访问一个类时想做一些访问控制

    关键代码

    • 目标类和代理类相结合

    优点:

    • 保护目标对象
    • 扩展性高
    • 职责清晰

    缺点:

    • 处理速度变慢
    • 实现可能会比较复杂

    注意:

    • 与装饰器模式区别:
      1.侧重于访问控制
      2.侧重于自己增加功能

    使用

    • 静态代理
    /**
     * 具体功能
     * @author 98543
     */
    public interface Func {
    
    	public void work();
    	
    	public void eat();
    	
    }
    /**
     * 具体对象
     * @author 98543
     */
    public class Targer implements Func{
    
    	@Override
    	public void eat() {
    		System.out.println("走啊,去吃饭");
    	}
    	
    	@Override
    	public void work() {
    		System.out.println("走啊,去工作");
    	}
    	
    }
    
    /**
     * 代理对象
     * @author 98543
     */
    public class Worker implements Func{
    	
    	private Targer laozong;
    	private Vistor vistor;
    	
    	public Worker(Targer laozong,Vistor vistor) {
    		this.laozong = laozong;
    		this.vistor = vistor;
    	}
    	
    	@Override
    	public void eat() {
    		System.out.println(vistor.getName()+"约老总去吃饭了");
    		laozong.eat();
    		System.out.println("他想 ->"+vistor.getWhat());
    	}
    	
    	@Override
    	public void work() {
    		System.out.println(vistor.getName()+"约老总去工作了");
    		laozong.work();
    		System.out.println("他想 ->"+vistor.getWhat());
    	}
    
    }
    // 静态代理
    Vistor vistor = new Vistor("张三","目的很纯粹啊");
    Targer MrLi = new Targer();
    Worker wk = new Worker(MrLi, vistor);
    wk.eat();
    wk.work();
    
    // 输出
    张三约老总去吃饭了
    走啊,去吃饭
    他想 ->目的很纯粹啊
    张三约老总去工作了
    走啊,去工作
    他想 ->目的很纯粹啊
    
    • jdk动态代理
    /**
     * 具体功能
     * @author 98543
     */
    public interface Func {
    
    	public void work();
    	
    	public void eat();
    	
    }
    /**
     * 具体对象
     * @author 98543
     */
    public class Targer implements Func{
    
    	@Override
    	public void eat() {
    		System.out.println("走啊,去吃饭");
    	}
    	
    	@Override
    	public void work() {
    		System.out.println("走啊,去工作");
    	}
    	
    }
    
    /**
     * 代理对象
     * @author 98543
     */
    public class Doctor implements InvocationHandler{
    	
    	private Targer laozong;
    	
    	public Doctor(Targer laozong) {
    		this.laozong = laozong;
    	}
    	
    	@Override
    	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    		System.out.println("1");
    		Object obj = method.invoke(laozong, args);
    		System.out.println("2");
    		return obj;
    	}
    
    }
    
    // jdk动态代理
    Doctor doctor = new Doctor(MrLi);
    Func func = (Func) Proxy.newProxyInstance(Vistor.class.getClassLoader(), new Class[] {Func.class}, doctor);
    func.eat();
    
    // 输出
    1
    走啊,去吃饭
    2
    
    • cglib动态代理
    /**
     * 具体对象
     * @author 98543
     */
    public class CglibTarget {
    	
    	public void drink() {
    		System.out.println("百事可乐");
    	}
    
    }
    
    // 代理类
    public class CglibProxy implements MethodInterceptor{
    	@Override
    	public Object intercept(Object arg0, Method arg1, Object[] arg2, MethodProxy arg3) throws Throwable {
    		System.out.println("第一步");
    		Object obj = arg3.invokeSuper(arg0, arg2);
    		System.out.println("第二步");
    		return obj;
        	}
        
        }
    // cglib动态代理(无需实现接口)
    Enhancer enhancer = new Enhancer();
    enhancer.setSuperclass(Sample.class);
    enhancer.setCallback(new CglibProxy());
    Sample sample = (Sample) enhancer.create();
    sample.eat();
    
    // 输出
    第一步
    yaxiyalei
    第二步
    

    jdk:
    基于反射,效率较慢,只能基于接口实现代理。
    cglib(注意jar包冲突问题):
    基于字节码,依赖于asm库,无需实现也可代理,使用继承实现代理,会生成一个子类,所以不能对final修饰的方法或类进行代理。

  • 相关阅读:
    线性方程组迭代法
    统计学习方法——朴素贝叶斯法、先验概率、后验概率
    信息熵、相对熵(KL散度)、交叉熵、条件熵
    六级听力词组积累
    样本均值和样本方差的无偏性证明、样本方差的方差
    Python 矩阵相关
    Python 绘图
    win10、VSCode、python3数据科学库
    Python杂记
    Gradient descend 梯度下降法和归一化、python中的实现(未完善)
  • 原文地址:https://www.cnblogs.com/kungFuPander/p/11474925.html
Copyright © 2020-2023  润新知