代理模式

代理模式是一种设计模式,简单说即是在不改变源码的情况下,实现对目标对象的功能扩展
情景如下:你想要跟小美约会看电影吃饭,要先经过他家人审查同意,小美才能出来看电影,看完电影小美的家人会问她中不中意你

1.首先定义一个女性接口(服务类),方法是看电影和吃饭


public interface Date {
    void watchMovie();
    void eatDinner();
}

2.定义小美(实现类),他是一个女性,他肯定可以看电影和吃饭

public class XiaoMei implements Date{

    @Override
    public void watchMovie() {
        System.out.println("我喜欢看电影");
    }
    @Override
    public void eatDinner() {
        System.out.println("晚饭不好吃");
    }
}

3.定义他的家人(代理类),可以给小美说去约会和吃饭吧


public class Family implements Date {
    private XiaoMei xiaomei;
    public Family(XiaoMei xiaomei){
        this.xiaomei = xiaomei;
    }
    @Override
    public void watchMovie() {
        System.out.println("家长同意 ");
        System.out.println("小美跟我去看电影");
        xiaomei.watchMovie();
    }
    @Override
    public void eatDinner() {
        System.out.println("家长同意 ");
        System.out.println("小美跟我去看吃饭");
        xiaomei.eatDinner();
    }
    /*
    *在这里,家长肯定持有小美的引用,这样在家长同意后,可以告诉小美去看电影和吃饭
    */
}

4.静态代理的使用

//创建小美(实现类对象)
Xiaomei xiaomei = new Xiaomei();
//创建小美的家人(代理类对象)
Family family = new Family(xiaomei);
//通过小美的家人约小美看电影和吃饭
family.watchMovie();
family.eatDinner();

5.动态代理的使用

//创建家人的代理,即我们不一定需要确定的家人,只要是小美的家人就行

public class FamilyProxy implements InvocationHandler{
    /**
     * target,目标对象
     */
    private Object target;

    /**
     *用于创建目标对象的代理的方法
     * @param target
     */
    public Object create(Object target) {
        this.target = target;
        Object proxy = Proxy.newProxyInstance(target.getClass().getClassLoader(),
                target.getClass().getInterfaces(),
                this);
        return proxy;
    }

    /**
     *
     * @param o 代理类对象
     * @param method 被代理类方法
     * @param objects 被代理类方法参数
     * @return
     * @throws Throwable
     */
    @Override
    public Object invoke(Object o, Method method, Object[] objects) throws Throwable {
    //前置增强
        System.out.println("家长同意了");
        method.invoke(target,objects);
    //后置增强
        System.out.println("家长问结果如何");
        return null;
    }
}

//接下来是动态代理的使用
//创建小美对象,类型为接口类型
Date xiaomei = new Xiaomei();
//创建家长代理的对象
FamilyProxy familyproxy = new FamilyProxy();
//创建小美的代理,类型为接口类型
Date obj = (Date)familyproxy.create(xiaomei);
//通知小美去约会
obj.watchMovie();
obj.eatDinner();

6.静态代理优缺点

1.优点
静态代理使客户端不需要知道实现类是什么,怎么做的,而客户端只需知道代理即可(解耦合)。
2.缺点
1)静态代理中代理类和委托类实现了相同的接口,代理类通过委托类实现了相同的方法导致代码重复,如果新增方法,工作量成倍增加。
2)静态代理中代理对象只服务于一种类型的对象,如果针对其他对象进行代理则需要新建。

7.动态代理优缺点

动态代理就是针对静态代理的缺点进行改进的,通过上面代码可以发现,即使在代理多个方法的时候,统一调用代理类中的invoke方法,更加方便灵活,不需要在每个代理方法中进行处理。

8.为什么使用代理

基于类的单一性原则(类越简单越好,这样修改的因子非常小,就很稳定了),如果我们需要对类的可操作性行进行检验,一个方法一个检查,会导致这个类很脆弱,任何一个检查规则的修改都可能导致这个类的修改,所以我们将可操作性的检验放在一个类中进行,这个类对可操作性性进行检查,如果合格就执行,不合格就不执行,这个类就是代理类,这个模式就是代理模式。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值