[英]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
界面上,這使您無法使用簡單的解決方案。 與其嘗試將Supplier
與Consumer
合並,不應該使用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
。 您可以根據需要使用Supplier
, Function
, BiFunction
或自定義interface
。
現在,指定的提供程序將使用它的參數,並且不會從其周圍的上下文中捕獲值,這使其保持不變(並且對於當前的實現,它將是單例)。
請注意,仍然可以實現僅忽略參數的提供程序功能,從而不會丟失基於Supplier
的解決方案的原始功能。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.