《设计模式之禅》读书笔记--(7)代理模式

定义

代理模式为其他对象提供一种代理以控制对这个对象的访问。

类图

这里写图片描述

Subject 抽象主题角色

Subject抽象主题角色可以是抽象类也可以是接口,是一个最普通的业务类型定义,无特殊要求。

RealSubject 具体主题角色

RealSubject具体主题角色是业务逻辑的具体执行者。

Proxy 代理主题角色

Proxy代理主题角色负责对真实角色的应用,把所有抽象主题类定义的方法限制委托给真实主题角色实现,并且在真实主题角色处理完毕前后做预处理和善后处理工作。

实现

抽象主题类:

package com.sigalhu.proxypattern;

public interface Subject {
    //定义一个方法
    public void request();
}

真实主题类:

package com.sigalhu.proxypattern;

public class RealSubject implements Subject {
    //实现方法
    @Override
    public void request() {
        //业务逻辑处理
    }
}

代理类:

package com.sigalhu.proxypattern;

public class Proxy implements Subject {
    //要代理哪个实现类
    private Subject subject = null;

    //默认被代理者
    public Proxy(){
        this.subject = new Proxy();
    }

    //通过构造函数传递代理者
    public Proxy(Subject subject){
        this.subject = subject;
    }

    //实现接口中定义的方法
    @Override
    public void request() {
        this.before();
        this.subject.request();
        this.after();
    }

    //预处理
    private void before(){
        //do something
    }
    //善后处理
    private void after(){
        //do something
    }
}
优点
  • 职责清晰,真实的角色就是实现实际的业务逻辑,不用关心其他非本职责的事务,通过后期的代理完成一件事务,附带的结果就是编程简洁清晰;
  • 高扩展性,具体角色类的不管如何变化,只要它实现了接口,代理类就可以在不做任何修改的情况下使用;
  • 智能化,参考AOP
动态代理

动态代理是在实现阶段不用关心代理谁,而在运行阶段才指定代理哪一个对象。

这里写图片描述

动态代理实现代理的职责,业务逻辑Subject实现相关的逻辑功能,两者之间没有必然的相互耦合的关系。通知Advice从另一个切面切入,最终在高层模块也就是Client进行耦合,完成逻辑的封装任务。

抽象主题:

package com.sigalhu.proxypattern.dynamicproxy;

public interface Subject {
    //业务操作
    public void doSomething(String str);
}

真实主题:

package com.sigalhu.proxypattern.dynamicproxy;

public class RealSubject implements Subject {
    //业务操作
    @Override
    public void doSomething(String str) {
        System.out.println("do something!-->" + str);
    }
}

动态代理的Handler类:

package com.sigalhu.proxypattern.dynamicproxy;

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

public class MyInvocationHandler implements InvocationHandler {
    //被代理的对象
    private Object target = null;

    //通过构造函数传递一个对象
    public MyInvocationHandler(Object object){
        this.target = object;
    }

    //代理方法
    @Override
    public Object invoke(Object proxy, Method method, Object[] args)
            throws Throwable{
        //执行被代理的方法
        return method.invoke(this.target, args);
    }
}

动态代理类:

package com.sigalhu.proxypattern.dynamicproxy;

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

public class DynamicProxy<T> {
    public static <T> T newProxyInstance(ClassLoader loader,
                                         Class<?>[] interfaces,
                                         InvocationHandler h){
        //寻找JoinPoint连接点,AOP框架使用元数据定义
        if(true){
            //执行一个前置通知
            (new BeforeAdvice()).exec();
        }
        //执行目标,并返回结果
        return (T) Proxy.newProxyInstance(loader,interfaces,h);
    }
}

通知接口及实现:

package com.sigalhu.proxypattern.dynamicproxy;

public interface IAdvice {
    //通知只有一个方法,执行即可
    public void exec();
}
package com.sigalhu.proxypattern.dynamicproxy;

public class BeforeAdvice implements IAdvice {
    @Override
    public void exec() {
        System.out.println("前置通知!");
    }
}

场景类:

package com.sigalhu.proxypattern.dynamicproxy;

import java.lang.reflect.InvocationHandler;

public class Client {
    public static void main(String[] args){
        //定义一个主题
        Subject subject = new RealSubject();
        //定义一个Handler
        InvocationHandler handler = new MyInvocationHandler(subject);
        //定义主题的代理
        Subject proxy = DynamicProxy.newProxyInstance(
                subject.getClass().getClassLoader(),
                subject.getClass().getInterfaces(),
                handler);
        //代理的行为
        proxy.doSomething("Finish");
    }
}
源码:https://github.com/SigalHu/DesignPatterns
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值