2012-08-16 50 views
0

這我不允許修改的回報我延長實例(需要一個模式推薦)

MyClass instance = ServiceUtil.getThing(); 

我想延長這個返回的類,並添加一個外部API服務的Java架構的問題/覆蓋一方法,但留下完整的其他人,說150種方法。

private class MyWrapperClass extends MyClass(){ 
     public MyWrapperClass(){super();} 
     @Override public String toString(){ return "Blocked toString"; } 
    } 

是否有任何方法強制從返回的MyClass實例的「鑄造」到我新的特定子類?

注意:請,不建議做一個構造函數,傳遞原始對象,並具有複製和落實150種方法的方法調用被包裝的對象

+0

即使您編寫了「MyClass」,您也沒有提及。返回的實例是類還是接口? – Less 2012-08-16 09:34:58

+1

@Less因爲'MyWrapperClass'擴展了'MyClass',所以它必須是一個類。 – maba 2012-08-16 09:50:44

回答

7

如果MyClass的是接口看看java.lang.reflect.Proxyjava.lang.reflect.InvocationHandler

您可以實現動態代理總是不一樣的。它總是把控制權交給你的原始實現......除非方法X被調用。

喜歡的東西:

class MyHandler implements InvocationHandler { 
    Object invoke(Object proxy, Method method, Object[] args) { 
    if (method is the one you want to change) { 
     do whatever 
    else 
     return method.invoke(originalObject, args); 
    } 
} 

注:你必須創建反正這個代理實現:

MyClass original = ServiceUtil.getThing(); 
MyClass proxy = (MyClass) Proxy.newProxyInstance(
              MyClass.class.getClassLoader(), // classloader to use 
              new Class[] { MyClass.class }, // interfaces to implement 
              new MyHandler()); // who does the dirty work when methods are invoked 
+0

並且...如果你喜歡這個,我應該把代理創建的東西放在'MyClass裝飾(MyClass)'方法中,把所有髒東西放在一起。如果你明天想改變裝修的方式,你只能改變這種方法。你的*正常*代碼不會被污染。 – helios 2012-08-16 09:52:27

+0

我認爲這是我正在尋找的答案 – Whimusical 2012-08-16 12:52:58

+0

太棒了! :) – helios 2012-08-17 01:09:30

1

請,不建議製作的方法構造函數,通過原始對象 和具有複製和落實150種方法來調用被包裝的對象

你的意思是說,「裝修」是不是你想看看右邊的選項?

但是裝飾將是您一個問題,如果MyClass的是,你必須定義這些150種奇方法中,委派149方法調用到裝飾和覆蓋一個方法的接口類型。

如果MyClass的是類類型,那麼你就不需要寫那些149點的方法,對嗎?還是我讓你完全錯了?

+0

他的類'MyWrapperClass' *擴展*'MyClass',所以'MyClass'不能是一個接口。 – 2012-08-16 09:39:03

+2

問題是他正在通過一個實例,而不是正好自己安裝一個自己 – 2012-08-16 09:40:16

+0

。如果沒有,我可以做一個匿名類實例化覆蓋方法,例如 – Whimusical 2012-08-16 12:51:57

5

我希望得到你的權利:你有一個

MyClass instance = ServiceUtil.getThing(); 

但想要像

MyWrapperClass instance = (MyWrapperClass) ServiceUtil.getThing(); 

(顯然不起作用,即使MyWrapperClass延伸MyClass)。

解決方法是根據MyClass創建一個MyWrapperClass的新實例,並且,很抱歉地說,使用構造函數是一種很好的方法(public MyWrapperClass(MyClass myClass))。

+1

+1「對不起,使用構造函數是一種很好的方法」 – helios 2012-08-16 09:53:37

+0

當然是這樣,但是接下來我需要重寫其他150個方法的超級調用(作爲底層對象的代理方法),這是不是一個很好的模式。 – Whimusical 2012-08-16 11:08:41

+1

無論如何,一個擁有150個方法的類並不是一個好的模式。所以它不會變得更糟;) – 2012-08-16 12:02:17