代理模式简介
代理模式就是给目标对象提供一个代理对象,并由代理对象控制对目标对象的引用。
代理模式必须要包含3个类:
- 抽象对象,即接口:定义了目标对象可以提供的服务。
- 真实对象,代理对象所代理的最终对象。
- 代理对象,访问者可以直接操作的对象。
代理模式好处
- 职责清晰 真实的角色就是实现实际的业务逻辑,不用关心其他非本职责的事务,通过后期的代理完成一件完成事务,附带的结果就是编程简洁清晰。
- 代理对象可以在客户端和目标对象之间起到中介的作用,这样起到了中介的作用和保护了目标对象的作用。
- 高扩展性
比如我想要在某个服务函数调用之前打个日志,那么一般就需要在业务逻辑中加一句话,修改了源码,可扩展性差,耦合度高,这时就可以使用代理模式,将服务交给代理类,让代理类完成打日志的任务。
静态代理
首先定义一个羊油供货商服务:
//羊油供货商
public interface MuttonFatSupplier {
public void saleOil();
}
以及一个实现类:
public class MuttonFatSupplierImp implements muttonFatSupplier{
@Override
public void saleOil() {
System.out.println("卖羊油");
}
}
定义一个羊油代理商
//羊油代理商
public class OilProxy implements MuttonFatSupplier {
// 真实对象的引用
private MuttonFatSupplier muttonFatSupplier;
public OilProxy() {
super();
}
public OilProxy(MuttonFatSupplier muttonFatSupplier) {
super();
this.muttonFatSupplier = muttonFatSupplier;
}
@Override
public void saleOil() {
System.out.println("调研羊油");
muttonFatSupplier.saleOil();
System.out.println("包装羊油");
}
}
这时直接使用羊油代理商获取羊油
public class Main {
public static void main(String[] args) {
MuttonFatSupplier muttonFatSupplier=new MuttonFatSupplierImp();//创建一个供应商
MuttonFatSupplier oilProxy=new OilProxy(muttonFatSupplier);//将供货商交给代理类
oilProxy.saleOil();//让代理商卖油
}
}
动态代理
假如现在有10个供货商,静态代理的工厂只能应对一种服务,如果想要扩展服务,就需要修改代理工厂源码,耦合性大,违反了开闭原则。
这时候就需要动态代理,使用一个通用代理工厂,代理各种服务,这就是动态代理的思想。
现在多加了个布丁供货商:
//布丁供货商
public interface PuddingSupplier {
public void sailPudding();
}
public class PuddingSupplierImp implements PuddingSupplier {
@Override
public void sailPudding() {
System.out.println("销售布丁");
}
}
创建动态代理工厂
public class UniversalProxy implements InvocationHandler {
private Object factory;
public Object getFactory() {
return factory;
}
public void setFactory(Object factory) {
this.factory = factory;
}
public Object getProxyInstance(){
return Proxy.newProxyInstance(factory.getClass().getClassLoader(),factory.getClass().getInterfaces(),this);
}
@Override
//通过动态代理的方式进行增强
/**
* proxy:代理类代理的真实代理对象com.sun.proxy.$Proxy0
* method:我们所要调用某个对象真实的方法的Method对象
* args:指代代理对象方法传递的参数
*/
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("售前服务");
Object ret=method.invoke(factory,args);
System.out.println("售后服务");
return ret;
}
}
进行服务
public static void main(String[] args) {
MuttonFatSupplier muttonFatSupplier=new MuttonFatSupplierImp();//创建一个羊油供应商
PuddingSupplier puddingSupplier=new PuddingSupplierImp();//创建一个布丁供应商
UniversalProxy universalProxy=new UniversalProxy();//创建一个通用代理
//开始买羊油
universalProxy.setFactory(muttonFatSupplier);
MuttonFatSupplier oilProxy=(MuttonFatSupplier)universalProxy.getProxyInstance();
oilProxy.saleOil();
//开始买布丁
universalProxy.setFactory(puddingSupplier);
PuddingSupplier puddingProxy=(PuddingSupplier)universalProxy.getProxyInstance();
puddingProxy.sailPudding();
}