2013-02-22 50 views
5

我看了一個代表java的代理模式的例子。沒有找到太多的用途(原諒無知),因爲我覺得它缺乏objective-c的靈活性。有沒有辦法像在objective-c中那樣動態設置委託對象。這不就是代表團的全部重點嗎?我對java的知識非常初步,所以請詳細解釋一下。如何在java中實現委託模式(如在objective-c中)

+0

[Java AWT Event architecture](http://docs.oracle.com/javase/1.4.2/docs/guide/awt/1.3/designspec/events.html)採用委託模型。您可能想要給該鏈接的文檔一個閱讀。 – Perception 2013-02-22 19:55:09

+0

@Perception:我檢查了鏈接。在給出的代碼示例中,傳遞的委託不必是「App」類型。這就是我所說的靈活性。或者我是完全錯誤的應用程序對象是委託? – Rakesh 2013-02-22 20:08:44

+0

前幾天在這裏http://stackoverflow.com/questions/14963740/cast-to-implemented-class/14963939#14963939我用一個例子勾畫了代表團模式,你可以檢查它。 – gaborsch 2013-02-22 20:11:49

回答

8

我認爲有很多種方式來實現委託模式在Java中的方式,但可能沒有哪個感覺像內置。

看看Wikipedia example。您的基本選擇是手動執行實現接口,然後將呼叫簡單地轉發到具體實例,您可以在運行期間儘可能多地更改它。

現在取決於你有哪些工具可以使用,你可以使這個轉發更自動。一個想法是使用面向方面的編程,如AspectJ。

具有縱橫編譯器(或運行時),你可以利用註釋和想出了一個簡單的擴展語言:

class Person { 
    @Delegate Animal animal; 
    ... 
} 

你會那麼必須編寫發現@Delegate秒的方面,並自動添加轉發類中的方法(如Person)接口。

如果您能夠使用a more groovy JVM language,那麼你甚至不必寫的一行代碼,因爲這種語言有標準庫代表:

你可以看看here,看看它是如何在Groovy中完成的。 (essentialy完全像我想出的Person示例語法...但內置!)

2

這就是你如何在Java中僞造一個功能性成語。是的,這很可怕。如果你想要優雅的功能性成語,請使用不會像紅頭兒童那樣處理功能的語言。如果您想要更多的編譯時安全性,那麼當然可以使用更具體的接口定義,這樣您就不會在編程錯誤的時候得到IndexOutOfBounds和ClassCastException。

public interface DelegatedFunction<T> { 

T call(Object... args); 

} 

public class DoesSomeDelegatedTask { 

    private List<DelegatedFunction<String>> delegatedFunctions = new ArrayList<>(1); 

    public void addFunction(DelegatedFunction<String> function) { 
    delegatedFunctions.add(function); 
    } 

    public void execute() { 
    for (DelegatedFunction<String> function: delegatedFunctions) { 
     System.out.println(function(something, someotherthing, whatever)); 
    } 
    } 
} 

public class Main { 
    public static void main(String[] args) throws Exception { 
    DoesSomeDelegateTask doer = new DoesSomeDelegatedTask(); 
    doer.addFunction(new DelegatedFunction<String>() { 
     @Override 
     public String call(Object... args) { 
     return ((SomeThings) args[0]).whatever((SomeOtherThing) args[1]//you get the idea 
     } 
    } 
    doer.execute(); 
    } 
}