代理模式
假如目前有一個(gè)Peoper類(lèi),實(shí)現(xiàn)了說(shuō)話的功能。
public class People {
public void say() {
System.out.println("Hello!");
}
}
現(xiàn)在我想要在說(shuō)話之前,添加一個(gè)思考的動(dòng)作。最簡(jiǎn)單的方法就是直接在方法前加上思考的動(dòng)作。
public class People {
public void say() {
System.out.println("思考!")
System.out.println("Hello!");
}
}
雖然問(wèn)題解決了,但是這樣做違反了面向?qū)ο蟮拈_(kāi)閉原則,如果代碼中其他地方也調(diào)用了這個(gè)方法,就會(huì)出現(xiàn)問(wèn)題。那么還可以添加一個(gè)新的方法,或者直接創(chuàng)建一個(gè)新的類(lèi)繼承People并重寫(xiě)say()方法來(lái)解決這個(gè)問(wèn)題,但是如果People類(lèi)有非常多的方法,我要在所有的方法前都加上思考動(dòng)作,這樣我就只能創(chuàng)建多新的方法或者在繼承類(lèi)中重寫(xiě)所有的方法并加上這個(gè)思考動(dòng)作,這樣會(huì)使代碼變得非常的冗余并且很不美觀。
為了解決的上述問(wèn)題,可以使用靜態(tài)代理的,但是靜態(tài)代理同樣需要添加為所有的方法添加額外統(tǒng)一的動(dòng)作,也會(huì)是代碼便的非常的冗余。
public class StaticPeopleProxy implements IPeople{
private People people;
public StaticPeopleProxy(){
this.people = new People();
}
@Override
public void say() {
System.out.println("思考!");
people.say();
}
@Override
public void walk() {
System.out.println("思考!");
people.walk();
}
}
為了解決上述問(wèn)題,動(dòng)態(tài)代理應(yīng)運(yùn)而生,jdk提供了invocationHandler接口和Proxy類(lèi),利用Proxy類(lèi)生成目標(biāo)對(duì)象的代理對(duì)象,通過(guò)實(shí)現(xiàn)invocationHandler接口的invoke()方法來(lái)實(shí)現(xiàn)統(tǒng)一的動(dòng)作。
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class PeopleProxyHandler implements InvocationHandler {
private Object targetObject;
public Object newProxyInstance(Object obj){
this.targetObject = obj;
return Proxy.newProxyInstance(targetObject.getClass().getClassLoader()
, targetObject.getClass().getInterfaces()
, this);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("思考!");
return method.invoke(targetObject, args);
}
}