java - 如何编写没有方法重载的通用 Java API

标签 java design-patterns variadic-functions overloading generic-programming

我有 2 个(或更多)数据源存储相同的内容;我想编写一个接口(interface),其中包含在其中查找项目的方法。示例:

public interface CarFinder {    
    public Car findById(String id);
}

然后我可以编写一个这样的类并使用它:

public class CustomCarFinder implements CarFinder {

    public Car findById(String id) {
        ...
        return someCar;
    }
}
...
Car aCar = customCarFinder.findById("1");

CustomCarFinder 知道如何连接到数据源并为我检索Car。 问题是,对于我的第一个数据源,每次我调用“findById”时,CustomCarFinder 都可以获取到它的连接;对于第二个数据源,知道如何获取连接的是 CarFinder 的客户端,而不是 CarFinder。为了向 CarFinder 提供连接信息,我编写了如下内容:

public interface CarFinder {

    public Car findById(String id, Object... context);

}

public class CustomCarFinder implements CarFinder {

    public Car findById(String id, Object... context) {
        //The Varargs (context) are not used in this version
        ...
        return someCar;
    }
}

public class AnotherCustomCarFinder implements CarFinder {

    public Car findById(String id, Object... context) {
        //Extract the connection here from the Varargs
        CustomConnection connection = (CustomConnection)context[0];
        ...
        //Somehow I find the car via this CustomConnection thing
        return someCar;
    }
}
...
Car aCar = customCarFinder.findById("1");
Car anotherCar = anotherCustomCarFinder.findById("1", aCustomConnection);

你看我使用了可变参数,这样我就可以使用 API 的任一版本。在第一种情况下,不必提供连接,我仍然可以使用:

Car aCar = customCarFinder.findById("1");

如果我需要提供连接:

Car anotherCar = anotherCustomCarFinder.findById("1", aCustomConnection);

Finder 类是作为 Spring 单例实现的,因此它们是共享的,因此为了避免线程问题,它们是无状态的,因此我不想在使用这些方法之前设置“连接”;这就是为什么我将连接作为 Varargs 传递。

还有其他方法可以做同样的事情吗? 关于使用 Varargs,我收到了反对意见(来自同事),我应该使用不同类型的连接类型重载“findById”方法。 我拒绝这样做,因为我不希望界面反射(reflect)我正在连接的数据源的类型。如果可能的话,我想要保留该界面:

public Car findById(String id);

我也不喜欢 Varargs,但我不知道如何摆脱它们并仍然完成我想要的。

最佳答案

Varargs 在需要时很好,但在这种情况下,我认为最好有一个用于连接的 setter 。

要使其可跨线程共享,您可以使用

public class AnotherCustomCarFinder implements CarFinder {
    private Pool<CustomConnection> connectionPool;

    public void setConnectionPool(Pool<CustomConnection> connectionPool) {
        this.connectionPool = connectionPool;
    }

    public Car findById(String id) {
        CustomConnection connection = connectionPool.acquire();
        //Somehow I find the car via this CustomConnection thing
        connectionPool.release(connection);
        return someCar;
    }
}

这样就可以写了

Car aCar = customCarFinder.findById("1");
Car anotherCar = anotherCustomCarFinder.findById("1");

关于java - 如何编写没有方法重载的通用 Java API,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53133025/

相关文章:

c++ - 可变参数 C++ 模板解压后终止?

java - 重写静态方法和多态性

java - 有没有更好的方法将数字转换为 Java 中具有可变十进制精度的填充字符串?

silverlight - MVVM:模型 View 如何与数据模型通信

spring-mvc - 请求 MVC 和组件 MVC 之间的区别

scala - Scala 中具有可变长度索引的 "update"方法

java - 了解具有多个类的多态性和实例化的接口(interface)形式

java - Android:在不影响电池生命周期的情况下将数据保存在 RAM 中

java - 避免大量实例化 "MyObjectX extends AbstractObject"来调用每个 myObjectX.execute() ?设计模式 ?

数组声明中的 PHP Spread 语法