zoukankan      html  css  js  c++  java
  • 设计模式-代理模式

    代理模式

    定义:由于某些原因需要给某对象提供一个代理以控制该对象的访问

    结构:

    • 抽象主题(Subject): 接口声明要实现的业务方法
    • 真实主题 (Real Subject): 实现抽象主题里的业务方法
    • 代理类(Proxy):提供了与真实主题相同的接口,它可以扩展、控制真实主题的功能。

    代理模式的结构很简单,是通过继承抽象主题的代理类来包含真实主题,从而来实现对真实主题的访问。

    代码示例:

    public interface Ticket {
    
        void buyTicket();
    }
    
    public class OfficialTicket implements Ticket {
        @Override
        public void buyTicket() {
            System.out.println("官方途径购票");
        }
    }
    
    public class ProxyTicket implements Ticket {
    
        private OfficialTicket officialTicket=new OfficialTicket();
    
        @Override
        public void buyTicket() {
            System.out.println("我把钱给了去哪网,委托购票");
            officialTicket.buyTicket();
        }
    }
    

    测试代码:

    public static void main(String[] args) throws InterruptedException, CloneNotSupportedException {
            ProxyTicket proxyTicket = new ProxyTicket();
            proxyTicket.buyTicket();
    

    以上就是代理模式的实现,也可以说是静态代理

    静态代理的局限性:

    1. 如果我们需要再增加一个需要代理的方法,那我们需要修改上面3个类,每个类都要加对应的逻辑。
    2. 如果我们想再代理一个其他的对象,也需要对代理类进行修改。

    那么如果用动态代理实现上面的代码会怎么样呢?

    Ticket类和OfficialTicket不变

    public class TicketInvocationHandler implements InvocationHandler {
    
        private Ticket ticket;
    
        public TicketInvocationHandler(Ticket ticket) {
            this.ticket = ticket;
        }
    
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            System.out.println("我把钱给了去哪网,委托购票");
            method.invoke(ticket,args);
            return null;
        }
    }
    

    测试代码:

    public static void main(String[] args) throws InterruptedException, CloneNotSupportedException {
         
            Ticket ticket = new OfficialTicket();
            //将操作者对象进行注入
            TicketInvocationHandler handler = new TicketInvocationHandler(ticket);
            //生成代理对象
            Ticket operationProxy = (Ticket) Proxy.newProxyInstance(ticket.getClass().getClassLoader(),
                    ticket.getClass().getInterfaces(), handler);
           operationProxy.buyTicket();
        }
    

    此时如果我们想增加一个退票方法,如果用动态代理,那么只需要改动Ticket类和OfficialTicket类。

    Cglib实现:

    public class TicketMethodInterceptor implements MethodInterceptor {
    
    
        @Override
        public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
            System.out.println("我把钱给了去哪网,委托购票");
            Object object = proxy.invokeSuper(obj, args);
            return object;
        }
    }
    

    测试代码:

     public static void main(String[] args) throws InterruptedException, CloneNotSupportedException {
            Enhancer enhancer = new Enhancer();
            // 设置enhancer对象的父类
            enhancer.setSuperclass(OfficialTicket.class);
            // 设置enhancer的回调对象
            enhancer.setCallback(new TicketMethodInterceptor());
            // 创建代理对象
            Ticket proxy= (Ticket)enhancer.create();
            // 通过代理对象调用目标方法
            proxy.buyTicket();
        }
    

    返回目录

    书山有路勤为径,学海无涯苦作舟
  • 相关阅读:
    第三节课 字符串拼接、格式化输出、深浅复制
    第四节课 集合、字典、运算符
    python-模块系列
    python正则表达式
    python第二天
    Python-第一天
    SQL SERVER 最近查询过的语句
    razor page 页面
    RAZOR显示表格数据
    邮件模板 C#
  • 原文地址:https://www.cnblogs.com/javammc/p/14947887.html
Copyright © 2011-2022 走看看