根据对象类型调用方法

Bri*_*isk 3 java generics design-patterns

我有两个辅助方法:

public String load(URL url) {...}
public String load(File file) {...}
Run Code Online (Sandbox Code Playgroud)

我想有一个方法,根据它接收的对象类型调用适当的帮助器方法:

public void operate(Object object) {...}
Run Code Online (Sandbox Code Playgroud)

我知道有一种令人费解的方式,它是:

public void operate(Object object) {
    String data = null;
    if (object.getClass().equals(File.class)) {
        data = load((File) object);
    }
    if (object.getClass().equals(URL.class)) {
        data = load((URL) object);
    }
    // operate on the data....
}
Run Code Online (Sandbox Code Playgroud)

然而,这似乎并不优雅,如果有更好的方式,我很好奇.

CKi*_*ing 5

然而,这似乎并不优雅,如果有更好的方法,那就很好奇.

那就对了.这违反了开放原则.类必须对扩展开放,但不能修改.当你说你需要一个通用的对象时,你也是对的.这是你可以做的:

创建Loader接口

public interface Loader<T> {
   public String load(T t);
}
Run Code Online (Sandbox Code Playgroud)

创建一个从File加载的加载器

public class FileLoader implements Loader<File> {
     public String load(File f) { 
            //load from file 
     }    
}
Run Code Online (Sandbox Code Playgroud)

创建一个从Url加载的加载器

public class UrlLoader implements Loader<Url> {
     public String load(URL r) { 
            //load from url 
     }    
}
Run Code Online (Sandbox Code Playgroud)

创建一个对数据进行操作的类

 class DataOperator<T> {
    Loader<T> loader;
    public SomeClient(Loader<T> loader) {
       this.loader = loader;
    }

    public void operate(T inputSource) {
       String data = loader.load(inputSource);
       //operate on the data
    }

 }
Run Code Online (Sandbox Code Playgroud)

然后客户端代码可以使用上面的API,如下所示:

DataOperator<File> fileDataOperator = new DataOperator<>(new FileLoader());
fileDataOperator.operate(new File("somefile.txt"));

DataOperator<URL> urlDataOperator = new DataOperator<>(new UrlLoader());
urlDataOperator.operate(new URL("http://somesite.com")); 
Run Code Online (Sandbox Code Playgroud)

你可能会认为这是解决一个简单问题的很多类.然而,这实际上与众所周知的开放式封闭设计原则相符.请注意如何通过创建适当类的实例来控制用于加载数据的技术.您获得的另一个优点是,您可以runtime通过创建一个Factory接受用户输入并创建适当的具体子类来决定使用哪种技术.这是策略模式的简化版本.

免责声明:上面提供的代码示例尚未针对编译错误进行测试,因为我Java在此计算机上没有.


Cup*_*Tae 4

一个稍微不那么复杂的方法是instanceof,例如

if (object instanceof File)) {
    data = load((File) object);
}
Run Code Online (Sandbox Code Playgroud)

然而,大多数时候,使用instanceof是一个标志,表明您想要实现的目标有更好的结构,例如

public void operate(File file) {
    operate(load(file));
}

public void operate(URL url) {
    operate(load(url));
}

public void operate(String data) {
    // operate on the data....
}
Run Code Online (Sandbox Code Playgroud)