設計模式——代理模式
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
總結:爲其他對象提供一種代理以控制對這個對象的訪問,重點在於控制對象的訪問!