2013-02-22 113 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(); 
    } 
}