繁体   English   中英

Java8 Supplier是可选的使用者

[英]Java8 Supplier that is an optional Consumer

我只能用示例来解释这一点。

我们有主类AppServer 它还包含几个应用程序范围内的组件。

AppServer app = new AppServer(config, ...);

现在,我们需要提供一个供应商,该供应商将充当某些Foo实例的工厂。 该供应商将在循环中多次调用,以创建一定数量的Foo实例。 通过使用供应商,我们允许用户提供他们自己的Foo实现。 请注意, Foo不是我们的课程,我们无法对其进行更改。

唯一的问题是Foo需要应用程序中的某些组件。 需要将它们注入/提供给FooImpl

可以这样写:

app.setFooSupplier(() -> new FooImpl(app.component()));

这对我来说有点丑陋,想知道是否有更好的方法可以做到这一点? 到目前为止,这里有一些想法...

(1)在使用供应商后注入依赖关系(IoC方式)。

依赖项由设置器定义。 所以我们在sudo中有类似(在AppServer内部):

Foo foo = fooSupplier.get();
maybeInject(foo, component1);
maybeInject(foo, component2);
...

注入什么成分取决于设置器是否在那里。 另外,我们可以拥有Component1Aware接口,并执行类似的操作:

Foo foo = fooSupplier.get();
if (foo instanceof Component1Aware) {
    ((Component1Aware)foo).setComponent1(component1);
}
...

基本上是一样的

我想在构造函数中具有依赖项,因此要表达它们需要进行设置。

(2)使用可选的使用者

FooImpl创建一个Supplier实例,同时将其作为AppServer Consumer 就像是:

public class FooImplSupplier implements Supplier<Foo>, Consumer<AppServer> {
    ...
}

然后我们可以很容易地注册该供应商:

app.setFooSupplier(new FooImplSupplier());

在供应商创建实例(在AppServer )之后,我们执行以下操作:

Foo foo = fooSupplier.get();
if (foo instanceof Consumer) {
    ((Consumer)foo).accept(this);
}

Wdyt?

我总是喜欢通过构造函数(或静态工厂方法)传递强制设置,我更喜欢的IoC样式是

app.setFooSupplier(() -> new FooImpl(app.component()));

或者,如果app.component()每次返回相同的内容,则可以编写以下内容。

Component comp = app.component();
app.setFooSupplier(() -> new FooImpl(comp));

到目前为止,这是最简单,最难弄错的。 例如,您不能传递参数0次或多次,或尝试在初始化之前使用Supplier。

向供应商提供上下文信息并不罕见。 您遇到的问题是您已固定在“ Supplier界面上,这使您无法使用简单的解决方案。 与其尝试将SupplierConsumer合并,不应该使用Function

void setFooProvider(Function<AppServer,Foo> f) {
  this.fooProvider=Objects.requireNonNull(f);
}
// …
// in a method within the same class:
    Foo foo=fooProvider.apply(this);

呼叫者:

app.setFooProvider(appArg -> new FooImpl(appArg.component()));

我将方法的名称从…Supplier更改为…Provider ,以表明所提供参数的作用并不特定于某个interface 您可以根据需要使用SupplierFunctionBiFunction或自定义interface

现在,指定的提供程序将使用它的参数,并且不会从其周围的上下文中捕获值,这使其保持不变(并且对于当前的实现,它将是单例)。

请注意,仍然可以实现仅忽略参数的提供程序功能,从而不会丢失基于Supplier的解决方案的原始功能。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM