我正在阅读这篇关于使用Optionals进行方法论证的文章,而且似乎一致认为永远不会将它们用于此目的。
Guava Optional as method argument for optional parameters
但是API方面(不是应用程序方面)根本没有这个规则的例外吗?我无法想出一种更清晰的方法来处理某些情况,尤其是在初始化情况下,可能会或可能不会使用参数参数。
利用这个可以构建的I&#m; m建筑物,提供我们企业使用的四个数据库连接。前三个不需要参数,因为DbManager
工厂已经拥有了所需的配置信息。但SQLite连接需要使用的SQLite数据库的URL。因此,我需要将Supplier
变为Function<Optional<String>,DatabaseConnection>
。
使用Optional
作为方法参数是否合法?如果不是,我怎么能使这个可枚举?
private static enum DbConnectionSupplier {
ORACLE(optArg -> DbManager.getOracleConnection()),
MYSQL(optArg -> DbManager.getMySQLConnection()),
TERADATA(optArg -> DbManager.getTeradataConnection()),
SQLITE(optArg -> DbManager.getSQLiteConnection(optArg.get()));
private final Function<Optional<String>, DatabaseConnection> supplier;
private DbConnectionSupplier(Function<Optional<String>, DatabaseConnection> supplier) {
this.supplier = supplier;
}
}
答案 0 :(得分:4)
首先,如果您正在使用lambda表达式,那么您正在使用Java 8进行编译,您可以使用java.util.Optional
而不是Guava。
我想你有以下方法:
DatabaseConnection getConnection(String arg) {
return supplier.apply(Optional.of(arg));
}
DatabaseConnection getConnection() {
return supplier.apply(Optional.empty());
}
现在,它不能保护您免受呼叫TERADATA.getConnection("BAR")
的人的侵害。另一方面,SQLITE.getConnection()
将NoSuchElementException
(Java8)或IllegalStateException
(番石榴)optArg.get()
失败,因为可选项为空。
从该异常中可以看出,在getConnection
中预期存在一个参数(嗯,可能很清楚,但是堆栈跟踪会因调用Function.apply
而被“污染”)
以下实现避免使用Optional
,并明确指出参数是否是预期的。
TERADATA(()-> DbManager.getTeradataConnection()),
SQLITE(arg -> DbManager.getSQLiteConnection(arg)),
FOO(()-> DbManager.getFooConnection(),
arg->DbManager.getFooConnection(arg));
//Foo supports both styles: with and without a parameter
private final Supplier<DatabaseConnection> supplier;
private final Function<String, DatabaseConnection> function;
private DbConnectionSupplier(Supplier<DatabaseConnection> supplier) {
this.supplier = supplier;
this.function = null;
}
private DbConnectionSupplier(Function<String, DatabaseConnection> function) {
this.function = function;
this.supplier = null;
} `
private DbConnectionSupplier(
Supplier<DatabaseConnection> supplier,
Function<String, DatabaseConnection> function) {
this.function = function;
this.supplier = supplier;
}
public DatabaseConnection getConnection(String arg) {
if (function==null) throw ...
return function.apply(arg);
}
public DatabaseConnection getConnection() {
if (supplier==null) throw ...
return supplier.get();
}