簡體   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