を襲ったユーザ嗜好システムとアプリケーションの次のユースケースを考えてみましょう:オプションの `orElse`遅延評価のパフォーマンスにリードを失敗は
我々は好みMyFlag
のbool値を取得したいです。
最高の場合、現在のユーザーの設定から使用することをお勧めします。
これが失敗した場合、MyFlag
をデフォルト設定から取得します。
それでも失敗した場合は、スローします。
設定はサーバー上にあります。この接続は遅く、失敗する可能性があります。
設定を取得して優先権を取得することもできます。
ので、使用javasのOptionalsをすることができます:ここ
public static boolean getMyFlag()throws NoSuchElementException
{
return getUserOrDefaultPreference("MY_FLAG");
}
private Boolean getUserOrDefaultPreference(String preferenceName) throws NoSuchElementException
{
return Optional.ofNullable(getConnection()) // get slow connection
.map(connection -> connection.getUserSettings()) // get user settings
.map(settings -> settings.getPref(preferenceName)) // return preference
.orElse(slowlyGetDefaultPreference(preferenceName)); // or else return default value
}
private Boolean slowlyGetDefaultPreference(String preferenceName) throws NoSuchElementException
{
return Optional.ofNullable(getConnection()) // get slow connection
.map(connection -> connection.getDefaultSettings()) // get default settings
.map(settings -> settings.getPref(preferenceName)) // return preference
.orElseThrow(() -> new NoSuchElementException()); // if any of the above fails throw
}
問題は、接続が非常に遅くなることができるということです。 .orElse(slowlyGet...);
が呼び出されると、func slowlyGetDefaultPreference()
が最初に評価されます。これは、オプションが空であるか値があるかどうかに関係なく、最初に評価されます。これはパフォーマンスのペナルティですが、私は避けなければなりません。
.orElseGet(() -> slowlytGet..)
でサプライヤを使用しようとしましたが、同じ問題が発生しました。
private Boolean getUserOrDefaultPreference(String preferenceName) throws NoSuchElementException
{
Optional<Boolean> opt = Optional.ofNullable(getConnection())
.map(connection -> connection.getUserSettings())
.map(settings -> settings.getPref(preferenceName));
if(opt.isPresent())
{
return opt.get();
}
else
{
slowlyGetDefaultPreference(preferenceName));
}
}
同じは私が支払うことをしたくないとして、例外をスローするために保持している:
だから私の唯一の頼みの綱は、読みやすさの観点から、全オプションの流れを台無しに醜いisPresent()
アンチパターンは、あります1つを構築するコスト。
ここに何かが見つからない、またはこれが唯一の解決策ですか?
'orElseGet'は最後の例とまったく同じように動作するはずですが、私はなぜそれが'orElse' – Magnus
@Magnusデバッガでコードをステップ実行したところ、' orElse'に対して 'getSlow ..()'が呼び出されました。 –
はい、orElseGetからの評価は、 'orElseGet'の前のある関数がnullオブジェクトを持っている場合にのみ呼び出されるためです。しかし、あなたが 'orElse'を使うと、常に – MateuszW90