代理模式是一种设计模式,简单说即是在不改变源码的情况下,实现对目标对象的功能扩展
情景如下:你想要跟小美约会看电影吃饭,要先经过他家人审查同意,小美才能出来看电影,看完电影小美的家人会问她中不中意你
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.为什么使用代理
基于类的单一性原则(类越简单越好,这样修改的因子非常小,就很稳定了),如果我们需要对类的可操作性行进行检验,一个方法一个检查,会导致这个类很脆弱,任何一个检查规则的修改都可能导致这个类的修改,所以我们将可操作性的检验放在一个类中进行,这个类对可操作性性进行检查,如果合格就执行,不合格就不执行,这个类就是代理类,这个模式就是代理模式。