Java 设计模式之代理模式(Proxy)

一、代理模式

代理模式为另一个对象提供一个替身或占位符以控制对这个对象的访问

 代理模式一般分为三类:静态代理、动态代理以及CGLIB代理。

二、静态代理

目标类和代理类都要实现接口

用户需求:火车票体系

需求分析:

  • 现在已经有国家正式的卖票软件12306,但是好像它并不好用
  • 智行代理售票,抢票概率高(这里没体现,现实我也没感觉),但是要加手续费

 类图设计:

Java 设计模式之代理模式(Proxy)_第1张图片

 代码示例:

tickBusiness 接口

package Proxy;

public interface ticketBusiness{
    public void checkLeftTickets();
    public void sellTickets();
}

ticket12306 具体类

package Proxy;

public class ticket12306 implements ticketBusiness{
    @Override
    public void checkLeftTickets() {
        System.out.println("查询余票");
    }

    @Override
    public void sellTickets() {
        System.out.println("卖票");
    }
}

zhixing 具体类

package Proxy;

public class zhixing implements ticketBusiness {
    private ticket12306 ticket12306;

    public zhixing(ticket12306 ticket12306) {
        this.ticket12306 = ticket12306;
    }

    @Override
    public void checkLeftTickets() {
        System.out.println("查询余票请输入智行身份认证");
        ticket12306.checkLeftTickets();
        System.out.println("欢迎继续使用智行");
    }

    @Override
    public void sellTickets() {
        System.out.println("智行购票便捷,抢票率高,手续费+5(呵呵呵)");
        ticket12306.sellTickets();
        System.out.println("智行永远为您服务");
    }
}

测试类

package Proxy;

public class ProxyTest {
    public static void main(String[] args) {
        ticket12306 t = new ticket12306();
        zhixing z = new zhixing(t);
        z.checkLeftTickets();
        z.sellTickets();
    }
}

三、JDK 动态代理

目标类需要实现接口,代理类不需要,利用Java的反射技术生成代理类

ticketBusiness ticket12306类跟上面的一样

ProxyTest测试类

package Proxy;

import java.lang.reflect.Proxy;

public class ProxyTest {
    public static void main(String[] args) {
        ticketBusiness t = new ticket12306();
        ticketBusiness tproxy = (ticketBusiness) Proxy.newProxyInstance(t.getClass().getClassLoader(), t.getClass().getInterfaces(), (proxy, method, args1) -> {
            System.out.println("加钱才卖票");
            Object invoke = method.invoke(t, args1);
            System.out.println("嘿嘿嘿");
            return invoke;
        });
        tproxy.sellTickets();
    }
}

还有一种代理模式是CGLIB代理,感兴趣的同学可以研究下

小结:

  • 静态代理:目标类和代理类都要实现接口,这样的代理类只能代理特定接口的对线,灵活度不够
  • 动态代理:代理类不需要实现接口,目标一定要实现接口
  • CGLIB代理:代理类也不需要实现接口,目标对象也可以是单纯一个对象
  • 动态代理和CGLIB代理在Spring的AOP编程中应用很频繁
  • 代理模式和装饰者模式的区别,在网上看到的例子,很有意思:
    • 代理模式:保护真实对象,控制权限
      • 孙悟空七十二变成高家小姐
      • 孙悟空和高家小姐具备共同的接口
      • 猪八戒可以看,但是不能摸,不能碰
    • 装饰器模式:动态的给对象添加更多的装饰,使对象功能加以扩展
      • 孙悟空七十二变,鱼儿,老虎,雄鹰等,在生物的基础上具备不同的本领
      • 在二郎神眼里,就是个猴子

你可能感兴趣的:(Java,设计模式)