代理模式

一、定义:
为其他对象提供一种代理以控制对这个对象的访问,在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。一个类代表另一个类的功能,这种类型的设计模式属于结构型模式。
二、结构
在这里插入图片描述
三、实现
代理模式分为:静态代理模式、动态代理模式
1、静态代理模式

//创建服务类接口
public interface BuyHouse {
    void buyHouse();
}

//实现服务类接口,中介

public class 中介 implements BuyHouse{

    private BuyHouse bh;
    
    中介(BuyHouse bh){
        this.bh = bh;
}
    
public void buyHouse() {
        System.out.println("你好,我是中介!你要买房吗?");
        bh.buyHouse();
        System.out.println("购房成功!");
    }
}

实现服务类接口,顾客

public class Customer implements BuyHouse{

    public void buyHouse() {
        System.out.println("我要买房子!");
    }
}

测试

public class Test {
    public static void main(String[] args) {
        BuyHouse cu = new Customer();
        中介 zj= new 中介(cu);
        zj.buyHouse();
    }
}

优缺点
优点:可以做到在符合开闭原则的情况下对目标对象进行功能扩展
缺点:我们得为每一个服务都得创建代理类,工作量太大,不易管理。同时接口一旦发生改变,代理类也得相应修改。

2、动态代理模式
创建服务类接口

//创建买车服务接口
public interface BuyCar {
    void buyCar();
}

//创建买房服务接口
public interface BuyHouse {
    void buyHouse();
}

编写动态处理器

//代理对象Proxy

public class ProxyDemo implements InvocationHandler {

    //实现InvocationHandler接口中的方法
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        if("toString".equals(method.getName())){
            return proxy.getClass().getName();
        }else if("buyHouse".equals(method.getName())){
            System.out.println("我是中介,为您提供买房服务!");
            return proxy;
        }else if("buyCar".equals(method.getName())){
            System.out.println("我是中介,为您提供买车服务");
            return proxy;
        }
        return null;
    }


   public static <M> M getInstance(Class<M> c){
        //得到类加载器的对象
        ClassLoader loader = ProxyDemo.class.getClassLoader();
        Class [] classes = {c};
        //得到当前类的对象
        ProxyDemo my = new ProxyDemo();
        //得到代理对象
        Object obj = Proxy.newProxyInstance(loader,classes,my);
        return (M)obj;
    }
}

顾客类

public class Client {
    public static void main(String[] args) {
        //顾客选择买房服务
        BuyHouse house = ProxyDemo.getInstance(BuyHouse.class);
        house.buyHouse();
    }
}

虽然相对于静态代理,动态代理大大减少了我们开发任务,同时减少了对业务接口的依赖,降低了耦合度。但还是一点点小遗憾,它始终无法摆脱仅支持interface代理。Java 的继承机制注定了这些动态代理类们无法实现对 class 的动态代 理,原因是多继承在 Java 中本质上就行不通。有很多条理由,人们 可以否定对class代理的必要性,但是同样有一些理由,相信支持class 动态代理会更美好。 接口和类的划分本就不是很明显,只是到了 Java 中才变得如此的细 化。如果只从方法的声明及是否被定义来考量,有一种两者的混合 体,它的名字叫抽象类。实现对抽象类的动态代理,相信也有其内 在的价值。

优缺点:
优点:
(1)职责清晰
(2)高扩展性
(3)智能化
缺点:
(1)由于在客户端和真实主体之间增加了代理对象,因此有些类型的代理模式可能会造成请求的处理速度变慢
(2)实现代理模式需要额外的工作,有些代理模式的实现非常复杂

四、适应场景
1、远程代理
2、虚拟代理
3、Copy-on-Write 代理
4、保护(Protect or Access)代理
5、Cache 代理
6、防火墙(Firewall)代理
7、同步化(Synchronization)代理
8、智能引用(Smart Reference)代理
五、应用
通过代码实现买火车票不一定在火车站买,也可以去代售点购买

//服务类接口
public interface BuyTrainTicket {
    void buyTrainTicket();
}

//代理
public class ProxyDemo implements InvocationHandler {

    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        if("buyTrainTicket".equals(method.getName())){
            System.out.println("你好,这里是火车票代购点!");
            System.out.println("你需要去哪里的票?");
            return proxy;
        }else if("toString".equals(method.getName())){
            return proxy.getClass().getName();
        }
        return null;
    }

    public static <T> T getInstance(Class<T> c){
        //得到类的加载器的对象
        ClassLoader loader = ProxyDemo.class.getClassLoader();
        Class [] classes = {c};
        //得到当前类的对象
        ProxyDemo proxyDemo = new ProxyDemo();
        //得到代理对象
        Object obj = Proxy.newProxyInstance(loader,classes,proxyDemo);
        return (T)obj;
    }
}

//顾客
public class Client {
    public static void main(String[] args) {
        BuyTrainTicket buyTrainTicket = ProxyDemo.getInstance(BuyTrainTicket.class);
        buyTrainTicket.buyTrainTicket();
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值