一、设计模式之代理设计
代理设计是在java开发中使用较多的一种设计模式,所谓的代理设计模式就是指一个代理主体操作真实主体,真实主体操作具体业务,代理主体负责给具体业务添砖加瓦。
就好比在生活中你有一套房子想要出租(你=真实主体),你找了房产中介(中介=代理主体)。真实主体负责提供房屋和收钱,代理主体负责带客户看房 、扣除手续费。租客只管租房子和付款,至于谁提供的房子并不关心。
我们发现,只需要定义一个租赁的接口,真实主体与代理主体都可以实现此接口,然后再由代理主体操作真实主体即可,上面的要求可以形成如下的代码:
1. 定义租赁接口
package com.javabasic.proxy;
/**
* 定义抽象接口
*/
public interface house {
/**
* 定义抽象方法 租赁
*/
void rent();
}
2. 定义真实主体 - 房东
package com.javabasic.proxy;
/**
* 定义真实主体 房东
*/
public class owner implements house{
@override
public void rent() {
system.out.println("房东提供房子,收取租金200元/月");
}
}
3. 定义代理主体 - 中介
package com.javabasic.proxy;
/**
* 定义代理主体 中介
*/
public class agent implements house{
// 接收真实主体 房东
private house house;
/**
* 通过构造方法,让中介与房东之间产生联系。
* 根据java动态绑定机制,house运行时的真实类型是房东类型,就可以获取到房东的出租行为。
* @param house
*/
public agent(house house){
this.house = house;
}
/**
* 中介对房东出租业务进行增强
*/
@override
public void rent() {
rentbefore();
house.rent(); // 房东 出租
rentafter();
}
private void rentbefore(){
system.out.println("中介负责寻找租客、带看、保存租客信息、签合同、收取租金。");
}
private void rentafter(){
system.out.println("中介负责租客退租后的清扫工作。");
}
}
4. 主程序 中介出租房屋
二、动态代理
上面讲解的代理机制的操作,属于静态代理,因为每一个代理类只能为一个接口服务,这样程序开发中必然会产生过多的代理类。最好的做法是可以通过一个代理类完成全部的代理功能
,那么此时就必须使用动态代理功能。
java 中想要实现动态代理的机制,则需要java.lang.reflect.invocationhandler接口
和 java.lang.reflect.proxy类
的支持。
invocationhandler接口的定义如下:
package java.lang.reflect;
public interface invocationhandler {
public object invoke(object proxy, method method, object[] args)
throws throwable;
}
proxy类是专门完成代理的操作类,可以通过此类为一个或多个接口动态地生成实现类。
/*
classloader loader : 类加载器
class<?>[] interfaces : 得到真实类实现的全部接口
invocationhandler h : 得到invocationhandler子类实例
*/
@callersensitive
public static object newproxyinstance(classloader loader,
class<?>[] interfaces,
invocationhandler h)
throws illegalargumentexception
{
...
}
房屋租赁代码修改如下 :
1. 需要房东实现租赁的接口
public interface house {
/**
* 定义抽象方法 租赁
*/
void rent();
}
public class owner implements house{
@override
public void rent() {
system.out.println("房东提供房子,收取租金200元/月");
}
}
2. 创建代理类(invocationhandler / proxy)
package com.javabasic.proxy;
import java.lang.reflect.invocationhandler;
import java.lang.reflect.method;
import java.lang.reflect.proxy;
public class agent2 implements invocationhandler {
// 接收真实主体
private object obj;
// 对外提供绑定真实主体方法
public object bind(object obj){
this.obj = obj;
// 通过真实对象创建代理对象并返回给调用者。
/*
proxy.newproxyinstance : 三个参数
类加载器 : this.obj.getclass().getclassloader()
真实类型实现的所有接口 : this.obj.getclass().getinterfaces()
代理类 : this
return 代理对象
*/
object object = proxy.newproxyinstance(this.obj.getclass().getclassloader(),
this.obj.getclass().getinterfaces(), this);
system.out.println("bind之后object真实类型 = " + object.getclass().getname());
return object;
}
/**
* 代理类会执行的方法。
* @param proxy 代理主体
* @param method 调用的方法
* @param args 方法的参数
*
* @return
* @throws throwable
*/
@override
public object invoke(object proxy, method method, object[] args) throws throwable {
system.out.println("proxy真实类型 = " + proxy.getclass().getname());
rentbefore();
method.invoke(this.obj, args); // 通过反射执行真实主体方法
rentafter();
return null;
}
private void rentbefore(){
system.out.println("中介负责寻找租客、带看、保存租客信息、签合同、收取租金。");
}
private void rentafter(){
system.out.println("中介负责租客退租后的清扫工作。");
}
}
发表评论