6、代理模式

6.1静态代理

角色分析
  • 抽象角色:一般会使用接口或者抽象类来解决
  • 真实角色:需要被代理的角色
  • 代理角色:代理真实角色,代理真实角色 后一般会在上面附加一些操作
  • 客户:访问代理角色的人,而不需要再直接与真实角色交涉
编程步骤
  • 接口(抽象角色)
public interface UserService {
    public void add();
    public void del();
    public void upa();
    public void sel();
}
  • 实现类(真实角色)
//真实的对象
public class UserServiceImpl implements UserService{
    @Override
    public void add() {
        System.out.println("增加一条数据 ...");
    }
    @Override
    public void del() {
        System.out.println("删除一条数据 ...");
    }
    @Override
    public void upa() {
        System.out.println("修改一条数据 ...");
    }
    @Override
    public void sel() {
        System.out.println("查看数据 ...");
    }
}
  • 代理类(代理角色 )
public class UserServicePorxy implements UserService{
    //找到需要代理的对象
    private UserService userService;
    public UserService getUserService() {
        return userService;
    }
    public void setUserService(UserService userService) {
        this.userService = userService;
    }
    @Override
    public void add() {
        log("add");
        userService.add();
    }
    @Override
    public void del() {
        log("del");
        userService.del();
    }
    @Override
    public void upa() {
        log("upa");
        userService.upa();
    }
    @Override
    public void sel() {
        log("sel");
        userService.sel();
    }
    //打印日志方法
    public void log(String meg){
        System.out.println("使用了"+meg+"方法");
    }
}
  • 客户类(客户)
public class Client {
    public static void main(String[] args) {
        //需要代理的真实对象
        UserService userService = new UserServiceImpl();
        //找到代理人
        UserServicePorxy userServicePorxy = new UserServicePorxy();
        //进行代理交接
        userServicePorxy.setUserService(userService);
        //通过代理执行相关操作
        userServicePorxy.add();
        userServicePorxy.del();
    }
}
优势
  • 代理模式会使真实角色的功能变得更加的纯粹,不需要去 关注一些公共的业务功能
  • 附加的一些公共的业务功能交给代理角色去实现,实现了业务的分工
  • 公共业务发生扩展的时候,方便集中管理
缺点
  • 每一个真实角色就需要一个代理角色,代码量会翻倍,降低开发的效率哦!

6.2动态代理

  • 动态代理和静态代理角色一样
  • 动态代理的代理类是动态生成的,不是直接写出来的
  • 动态代理分为两大类:基于接口的动态代理,基于类的动态代理
  • 基于接口-JDK动态代理(我们在这里使用)
  • 基于类-cglib
  • java字节码实现-javasist
  • 需要了解两个类:Proxy代理,invocationhandler调用处理程序
优势
  • 在静态代理的优势之上,另外有
  • 一个动态代理类代理的是一个接口,一般就对应一类业务
  • 一个动态代理类可以代理多个类,只要是实现了同一个接口
编程
  • 接口(同上)

  • 实现类(同上)

  • 代理的工具类

//我们可以把这个类看作是一个工具类
//我们会用这个类自动生成代理类
public class ProxyInvocationHandler implements InvocationHandler {
    //被代理的解接口
    private Object target;
    //动态获取需要被代理的接口
    public void setTarget(Object target) {
        this.target = target;}
    //生成得到代理类
    public Object getProxy(){
        return Proxy.newProxyInstance(this.getClass().getClassLoader(), target.getClass().getInterfaces(),this);}
    @Override
    //处理代理实例,并返回结果
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        log(method.getName());
        Object result = method.invoke(target, args);
        return result;}
    //扩展业务功能
    public void log(String msg){
        System.out.println("执行了"+msg+"方法");}}
  • 客户类
public class Client {
    public static void main(String[] args) {
        //真实角色是必须要有的
        UserServiceImpl userService =  new UserServiceImpl();
        //现在没有代理类,我们需要使用那个工具类去生成获取代理
        //生成工具
        ProxyInvocationHandler pih = new ProxyInvocationHandler();
        //指定需要代理的真实角色到工具类中
        pih.setTarget(userService);
        //通过工具类生成并获取到代理类(这里需要注意返回的代理类应该是属于被代理的接口类型)
        UserService proxy = (UserService)pih.getProxy();
        //通过代理执行操作
        proxy.del();
    }
}
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容