多くのWebサイトで読みましたOptionalは戻り値の型としてのみ使用し、メソッドの引数では使用しないでください。論理的な理由を見つけるのに苦労しています。たとえば、2つのオプションパラメータを持つロジックがあります。したがって、次のようにメソッドシグネチャを記述することは理にかなっていると思います(ソリューション1):
public int calculateSomething(Optional<String> p1, Optional<BigDecimal> p2 {
// my logic
}
多くのWebページでは、オプションをメソッドの引数として使用しないでください。これを念頭に置いて、次のメソッドシグネチャを使用して明確なJavadocコメントを追加し、引数がnullになる可能性があることを指定します。将来のメンテナがJavadocを読み、引数を使用する前に常にnullチェックを実行することを期待します(解決策2) :
public int calculateSomething(String p1, BigDecimal p2) {
// my logic
}
または、より良いインターフェイスを提供し、p1とp2がオプションであることをより明確にするために、メソッドを4つのパブリックメソッドに置き換えることもできます(ソリューション3)。
public int calculateSomething() {
calculateSomething(null, null);
}
public int calculateSomething(String p1) {
calculateSomething(p1, null);
}
public int calculateSomething(BigDecimal p2) {
calculateSomething(null, p2);
}
public int calculateSomething(String p1, BigDecimal p2) {
// my logic
}
次に、各アプローチのこのロジックを呼び出すクラスのコードを記述してみます。最初に、Optional
s を返す別のオブジェクトから2つの入力パラメーターを取得し、次にを呼び出しcalculateSomething
ます。したがって、ソリューション1を使用する場合、呼び出しコードは次のようになります。
Optional<String> p1 = otherObject.getP1();
Optional<BigInteger> p2 = otherObject.getP2();
int result = myObject.calculateSomething(p1, p2);
ソリューション2を使用する場合、呼び出しコードは次のようになります。
Optional<String> p1 = otherObject.getP1();
Optional<BigInteger> p2 = otherObject.getP2();
int result = myObject.calculateSomething(p1.orElse(null), p2.orElse(null));
ソリューション3が適用されている場合、上記のコードを使用するか、次のコードを使用できます(ただし、コードが大幅に増えます)。
Optional<String> p1 = otherObject.getP1();
Optional<BigInteger> p2 = otherObject.getP2();
int result;
if (p1.isPresent()) {
if (p2.isPresent()) {
result = myObject.calculateSomething(p1, p2);
} else {
result = myObject.calculateSomething(p1);
}
} else {
if (p2.isPresent()) {
result = myObject.calculateSomething(p2);
} else {
result = myObject.calculateSomething();
}
}
だから私の質問です:Optional
sをメソッドの引数として使用するのはなぜ悪い習慣と考えられているのですか(解決策1を参照)? それは私にとって最も読みやすいソリューションのように見え、将来のメンテナーにとってパラメーターが空/ nullである可能性があることが最も明白になります。(私は設計者がOptional
それを戻り値の型としてのみ使用することを意図していたことを知っていますが、このシナリオでそれを使用しない論理的な理由を見つけることができません)。
null
か?