在
上一篇隨筆
中,由于時間和篇幅的關系只是簡單介紹了Proxy模式的概念,并沒有寫到Java中對Proxy模式特有的支持,所以嚴格說起來是有點"名不符實",現在就接著介紹JDK中Proxy模式的實現:
Java API中提供了對Proxy模式的支持,主要是通過反射(Reflect)包中的Proxy類和InvocationHandler接口實現,具體過程如下:
----------------------------------------------------------------
(1) 實現InvocationHandler接口,在invoke()方法中實現代理類要完成的操作;
(2) 通過Proxy.newProxyInstance(ClassLoader loader,Class[]
interfaces,InvocationHandler h)方法生成一個代理類,從參數可以看出代理類將實現被代理對象的接口,而具體的實現過程是在上面實現的InvocationHandler.invoke()中定義的.
----------------------------------------------------------------
我們還是用演藝圈的例子來說明:
首先,類的關系圖需要修改一下:

可以看出,這里并沒有經紀人(Broke)類,而是新增了一個經紀人操作類(BrokeHandler),這是因為通過Proxy.newProxyInstance()方法,Java API將自動為我們生成一個對于Artist接口的代理類(即:Broke),我們只需定義代理的操作即可.
經紀人工作:
/**?*/
/**
?*?經紀人工作
?*?
?*?
@author
?zjun
?*?
@version
?1.0?create?on?2006-4-11?18:06:36
?
*/
public
?
class
?BrokerHandler?
implements
?InvocationHandler?
{

????
private
?String?SIGN?
=
?
"
?[經紀人工作]?
"
;

????
//
?旗下明星
????
private
?Star?star;


????
public
?BrokerHandler(Star?star)?
{
????????
this
.star?
=
?star;
????}
????
/**?*/
/**
?????*?簽訂和約
?????
*/
????
private
?
void
?subcontract()?
{
????????System.out.println(SIGN?
+
?
"
?簽訂和約?
"
);
????}
????
/**?*/
/**
?????*?演出后交稅
?????
*/
????
private
?
void
?payTax()?
{
????????System.out.println(SIGN?
+
?
"
?演出后交稅?
"
);
????}
????
/**?*/
/**
?????*?
@see
?java.lang.reflect.InvocationHandler#invoke(java.lang.Object,
?????*??????java.lang.reflect.Method,?java.lang.Object)
?????
*/
????
public
?Object?invoke(Object?proxy,?Method?method,?Object[]?args)

????????????
throws
?Throwable?
{
????????Object?obj?
=
?
null
;
????????
//
?簽約
????????subcontract();
????????
//
?安排藝人演出
????????obj?
=
?method.invoke(star,?args);
????????
//
?交稅
????????payTax();
????????
return
?obj;
????}
}
藝人:
/**?*/
/**
?*?藝人
?*?
?*?
@author
?zjun
?*?
@version
?1.0?create?on?2006-4-11?18:05:48
?
*/
public
?
interface
?Artist?
{
????
public
?
void
?show(String?showType);
}
明星:
/**?
?*?明星
?*?
?*?
@author?zjun
?*?
@version?1.0?create?on?2006-4-11?18:08:17
?
*/
public
?
class
?Star?
implements
?Artist?
{
????
private
?String?SIGN?
=
?
"
?[明星]?
";


????
public
?
void
?show(String?showType)?
{
????????System.out.println(SIGN?
+?showType);
????}
}
演出贊助商:
/**
?*?演出贊助商
?*?
?*?
@author?zjun
?*?
@version?1.0?create?on?2006-4-11?18:30:25
?
*/
public
?
class
?Patron?
{


????
/**?*//**
?????*?
@param?args
?????
*/
????public
?
static
?
void
?main(String[]?args)?
{
????????Star?star?
=
?
new?Star();
????????BrokerHandler?broker?
=
?
new?BrokerHandler(star);
????????Artist?b?
=?(Artist)?Proxy.newProxyInstance(star.getClass()
????????????????.getClassLoader(),?star.getClass().getInterfaces(),?broker);
????????b.show(
"
?演電影?
");
????????b.show(
"
?拍電視?
");
????????b.show(
"
?出唱片?
");
????????b.show(
"
?演唱會?
");

????}
}
[運行結果]:
?
[
經紀人工作
]??簽訂和約?
?
[
明星
]??演電影?
?
[
經紀人工作
]??演出后交稅?
?
[
經紀人工作
]??簽訂和約?
?
[
明星
]??拍電視?
?
[
經紀人工作
]??演出后交稅?
?
[
經紀人工作
]??簽訂和約?
?
[
明星
]??出唱片?
?
[
經紀人工作
]??演出后交稅?
?
[
經紀人工作
]??簽訂和約?
?
[
明星
]??演唱會?
?
[
經紀人工作
]
??演出后交稅?