1. 程式人生 > >設計模式——(代理模式)

設計模式——(代理模式)

近期著實的想回顧一下自己已經忘得差不多的設計模式

先從代理模式開始吧
  1. 代理模式:簡單的講代理就是中介,中間人。法律上也有代理,比如代理律師之類,委託人將自己的一部分許可權委託給代理者,代理者就擁有被代理者(委託人)的部分許可權,並且可以以被代理人的名義來實行這些許可權,此時代理者與委託人等同,當然代理人也可以在實行許可權時配合自己的能力來進行,當然不能超出這個許可權。
      Java中的代理模式類似於上面的代理,我們也是為一個類(委託類)建立一個代理類,來代表它來對外提供功能。
      如何在Java中建立一個類的代理類呢?
      很簡單,我們需要建立一個公共介面,委託類要實現這個介面,再建立一個介面的實現類作為代理類,在這個類中的方法中可以直接呼叫委託類中的同名方法,外部類要進行訪問時,可以使用介面指向代理類例項,呼叫代理類中的方法,從而間接呼叫委託類中的具體方法實現。
  2. 我們就以法律上的委託代理為例來寫個例項:
/* 定義人這個介面*/
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(); } }
  1. 當然代理還分為動態代理以及靜態代理
    靜態代理
    以上面程式碼為例:
    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切面也是通過動態代理所實現的。