設計模式——(代理模式)
阿新 • • 發佈:2018-12-21
近期著實的想回顧一下自己已經忘得差不多的設計模式
先從代理模式開始吧
- 代理模式:簡單的講代理就是中介,中間人。法律上也有代理,比如代理律師之類,委託人將自己的一部分許可權委託給代理者,代理者就擁有被代理者(委託人)的部分許可權,並且可以以被代理人的名義來實行這些許可權,此時代理者與委託人等同,當然代理人也可以在實行許可權時配合自己的能力來進行,當然不能超出這個許可權。
Java中的代理模式類似於上面的代理,我們也是為一個類(委託類)建立一個代理類,來代表它來對外提供功能。
如何在Java中建立一個類的代理類呢?
很簡單,我們需要建立一個公共介面,委託類要實現這個介面,再建立一個介面的實現類作為代理類,在這個類中的方法中可以直接呼叫委託類中的同名方法,外部類要進行訪問時,可以使用介面指向代理類例項,呼叫代理類中的方法,從而間接呼叫委託類中的具體方法實現。 - 我們就以法律上的委託代理為例來寫個例項:
/* 定義人這個介面*/
public interface Person{
public void doSomething();
}
然後我們再來生成委託人類
/*委託人*/
public class Wtr implements Person{
@Override
public void doSomething(){
System.out.print("我再讓我律師給你交談");
}
}
最後我們來讓律師執行
/*律師類*/
public class Ls implement Person{
private Person p;
public Ls(Person p){
this.p = p;
}
@Override
public void doSomething(){
p.doSomething();
}
}
- 當然代理還分為動態代理以及靜態代理
靜態代理:
以上面程式碼為例:
輸出的結構為:public staitc void main(String [] args){ //s為被代理的物件,某些情況下 我們不希望修改已有的程式碼,我們採用代理來間接訪問 Wtr s = new Wtr (); //建立代理類物件 Ls proxy = new Ls(s); //呼叫代理類物件的方法 proxy.doSomething
我再讓我律師給你交談
靜態代理看起來是比較簡單的,沒有什麼問題只不過是在代理類中引入了被代理類的物件而已。
動態代理:若是動態代理,他可以代理多個不通的委託類
/**
* 動態代理,動態代理類不要顯示的實現被代理類所實現的介面
* @author yujie.wang
*
*/
public class MyInvocationHandler implements InvocationHandler{
private Object object;
public MyInvocationHandler(Object object){
this.object = object;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
System.out.println("我插一句,我開始敘述了:");
method.invoke(object, args);
System.out.println("我敘述完畢!");
return null;
}
}
代理類:
public class PersonProxy {
private Object target;
private InvocationHandler ph;
public PersonProxy(Object target,InvocationHandler ph){
this.target = target;
this.ph = ph;
}
public Object getPersonProxy(){
Object p = Proxy.newProxyInstance(target.getClass().getClassLoader(),target.getClass().getInterfaces(),ph);
return p;
}
}
測試類:
/**
* 測試類
*/
public class App {
public static void main(String[] args) {
// 目標物件
Wtr target = new Wtr ();
InvocationHandler inv = new MyInvocationHandler(target);
// 給目標物件,建立代理物件
Person proxy = (Person) new PersonProxy(target,inv).getPersonProxy();
// class $Proxy0 記憶體中動態生成的代理物件
// 執行方法 【代理物件】
proxy.doSomething();
}
}
輸出結果為:
我插一句,我開始敘述了:
我再讓我律師給你交談
我敘述完畢!
ps:我們所熟悉的springAop切面也是通過動態代理所實現的。