设计模式——代理模式
1- 代理模式的定义
代理模式:使用一个对象表示另外一个对象的功能,在代理模式中,我们可以创建持有现有对象的对象,以便向外界提供功能接口!
No BB,Show Code!
2- 代理模式的具体实现代码
2-1使用JDK自带的InvocationHandler接口实现代理功能
使用JDK中java.lang.reflect包下的InvocationHandler接口实现代理功能,代码如下:
1-定义个接口
package designPattern.test.proxy.jdk;
/**
* 歌手接口
*/
public interface Singer {
//商谈
void confer();
//签约
void signContext();
//订车票
void bookTicket();
//唱歌
void sing();
//收钱
void collectMoney();
}
2-定义一个Singer接口的实现类
package designPattern.test.proxy.jdk;
/**
* Singer具体的实现类
*/
public class JayZhou implements Singer {
@Override
public void confer() {
System.out.println("JayZhou confer");
}
@Override
public void signContext() {
System.out.println("JayZhou signContext");
}
@Override
public void bookTicket() {
System.out.println("JayZhou bookTicket");
}
/**
* 只有这一步是JayZhou自己来的,其他的步骤都应交给代理类执行
*/
@Override
public void sing() {
System.out.println("JayZhou sing");
}
@Override
public void collectMoney() {
System.out.println("JayZhou collectMoney");
}
}
3-创建代理类
package designPattern.test.proxy.jdk;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
/**
* 经纪人类:代理歌手做除了唱歌以外的所有事
* InvocationHandler是JDK中reflect包下的接口
* JDK自动的代理工具
*/
public class Agent implements InvocationHandler {
private Singer singer;
public Agent(Singer singer) {
super();
this.singer = singer;
}
/**
* 通过反射的方式执行方法
* 如果是single则调用Singer.sing方法
* 代理类执行
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if ("sing".equals(method.getName())) {
method.invoke(singer, args);
} else {
System.out.println("经纪人完成!");
}
return null;
}
}
2-4测试代码
package designPattern.test.proxy.jdk;
import org.junit.Test;
import java.lang.reflect.Proxy;
/**
* 代理模式测试
*/
public class ProxyTest {
@Test
public void testProxy() throws Exception {
Singer singer = new JayZhou();
Agent agent = new Agent(singer);
Singer proxy = (Singer)Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(), new Class[]{Singer.class}, agent);
proxy.bookTicket();
proxy.sing();
}
}
打印结果
经纪人完成!
JayZhou sing
2-2动态代理
被代理类和代理类实现相同的接口。
1-定义一个接口:
package designPattern.test.proxy.dynamic;
/**
* 接口:租房子
*/
public interface Renting {
/**
* 找房子方法,交给代理人执行
*/
void renting(String apply);
/**
* 付房租方法,自己执行
*/
void pay(Double money);
}
2-被代理类:
package designPattern.test.proxy.dynamic;
/**
* 实际需要租房子的人
*/
public class Renter implements Renting {
/**
* 实际租房人租房
*/
@Override
public void renting(String apply) {
System.out.println("Renter renting-apply:" + apply);
}
/**
* 实际租房人付房租
*/
@Override
public void pay(Double money) {
System.out.println("Renter renting-pay:" + money);
}
}
3-代理类:
package designPattern.test.proxy.dynamic;
/**
* 租房代理
*/
public class RenterProxy implements Renting{
private Renter renter;
public RenterProxy(Renter renter) {
this.renter = renter;
}
/**
* 租房代理租房
*/
@Override
public void renting(String apply) {
System.out.println("RenterProxy renting-apply:" + apply);
}
/**
* 实际租房人自己付房租
*/
@Override
public void pay(Double money) {
renter.pay(money);
}
}
4-测试代码
package designPattern.test.proxy.dynamic;
import org.junit.Test;
/**
* 动态代理测试
*/
public class ProxyTest {
@Test
public void testProxy(){
Renter renter = new Renter();
Renting proxy = new RenterProxy(renter);
proxy.renting("在北五环附近找个3000左右的单间");
proxy.pay(3100.0);
}
}
打印结果
RenterProxy renting-apply:在北五环附近找个3000左右的单间
Renter renting-pay:3100.0
总结:为其他对象提供一种代理以控制对这个对象的访问,重点在于控制对象的访问!