定义:由于某些原因访问对象(购房者)不能或不想直接和目标对象(开发商)进行访问,需要通过代理(中介)来帮助完成
优点:
缺点:
应用场景:
结构:
主要是通过定义一个继承抽象主题的代理,该代理包含真实主题,从而实现对真实主题的访问
根据代理的创建时期,代理模式分为静态代理和动态代理
实现
public class ProxyTest {
public static void main(String[] args) {
HouseProxy houseProxy = new HouseProxy(new RealHouse());
houseProxy.buyHouse();
}
}
// 抽象主题:房子模型
interface House {
void buyHouse();
}
// 真实主题:真实的房子
class RealHouse implements House {
public void buyHouse() {
System.out.println("这是您买的一套毛坯江景房");
}
}
// 代理:房产中介。可以代理不同的House
class HouseProxy implements House {
private House realHouse;
public HouseProxy(House house) {
this.realHouse = house;
}
// 只能代理固定的业务,不能动态发展新的业务
public void buyHouse() {
preBuyHouse();
this.realHouse.buyHouse();
postBuyHouse();
}
// 买房前提供的服务
public void preBuyHouse() {
System.out.println("中介买房前提供的服务");
}
// 买房后提供的服务
public void postBuyHouse() {
System.out.println("中介买房后提供的服务");
}
}
运行程序,结果如下:
中介买房前提供的服务
这是您买的一套毛坯江景房
中介买房后提供的服务
前面我们使用静态代理,发现真实主题每增加一个业务方法,代理主题也必须同步增加一个业务方法。现在我们使用动态代理方式解决
动态代理模式,是通过实现Java的java.lang.reflect.InvocationHandler这个接口,通过反射来对真实主题进行实例化,然后通过反射动态的执行方法。实现参考如下:
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class ProxyTest {
public static void main(String[] args) {
HouseRelatedProxy houseRelatedProxy = new HouseRelatedProxy();
HouseRelated houseRelated = houseRelatedProxy.getInstance(new RealHouseRelated());
houseRelated.buyHouse();
System.out.println("==================");
houseRelated.decorate();
}
}
// 抽象主题:房子相关模型
interface HouseRelated {
void buyHouse();
void decorate();
}
// 真实主题:真实的房子相关产品
class RealHouseRelated implements HouseRelated {
public void buyHouse() {
System.out.println("这是您买的一套毛坯江景房");
}
public void decorate() {
System.out.println("江景房已经给您装修好了");
}
}
// 代理:房产相关业务的中介。可以代理不同的House,后续还可以动态的发展新的业务,比如装修、代理家具
class HouseRelatedProxy implements InvocationHandler {
private HouseRelated houseRelated;
public HouseRelated getInstance(HouseRelated houseRelated) {
this.houseRelated = houseRelated;
Class> houseRelatedClass = this.houseRelated.getClass();
// 返回中介的一个代理实例(真实主题)。基于反射的原理
/*
三个参数含义:
1. classLoader:加载动态生成的类加载器
2. interfaces:目标对象实现的所有接口的class对象所组成的数组
3、invocationHandler:设置代理对象实现目标对象方法的过程,即代理类中如何重写InvocationHandler接口中的invoke抽象方法
*/
return (HouseRelated) Proxy.newProxyInstance(houseRelatedClass.getClassLoader(), houseRelatedClass.getInterfaces(), this);
}
// 在客户端调用代理实例(真实主题)的方法,会自动跳转到执行这个方法。基于反射的原理
// 可以动态发展新的业务
/*
三个参数含义:
1. proxy:代理对象
2. method:目标对象的方法
3. args:method所对应方法的参数
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
preHouseRelated();
Object result = method.invoke(this.houseRelated, args);
postHouseRelated();
return result;
}
// 房产相关前提供的服务
public void preHouseRelated() {
System.out.println("房产相关前提供的服务");
}
// 房产相关后提供的服务
public void postHouseRelated() {
System.out.println("房产相关后提供的服务");
}
}
运行程序,结果如下:
房产相关前提供的服务
这是您买的一套毛坯江景房
房产相关后提供的服务
==================
房产相关前提供的服务
江景房已经给您装修好了
房产相关后提供的服务