オプションのパラメーターを使用してBuilderをよりエレガントに実行できるのではないかと思っていました。
私が持っているもの:名前、ID、年齢を持つオブジェクト。
年齢を含めるための複雑な条件があり、その条件の成功時にビルダーに送信したいのですが、1つのパラメーターを持つエレガントな1つのライナーにしたいと思います。
私がこれまでに持っているもの:
Builder.name("name").id("id").age(age, complexCondition).build();
または
Builder builder = Builder.name("name").id("id");
if(complexCondition){
builder.age(age);
}
より良いオプションはありますか?すべての複雑な条件チェックのために、オーバーエンジニアリングビルダーやオーバーコーディングをせずに、問題が発生している状態を解決したいと思います。
upd:私が探しているのは、以下のないソリューションです:
a)complexChecksまたはbooleansをビルダーに渡す-定義によるチェックの仕事ではありません
b)ビルダーを呼び出すメソッド内の条件チェックごとに3行を追加しない
私の答えはそれをシンプルに保つことです。ビルダーの責任は、オブジェクトを構築することです。条件を評価するための複雑なDSLを提供しないこと。したがって、2番目のスニペットは完全に問題ありません。
ビルダーへの呼び出しとインターレースされた多数のif
チェックによるコードの過負荷を避けるために必要なのは、これらのチェックのコードをメソッドに抽出することです。だからあなたはから行くことができます
Builder builder = Builder.name("name").id("id");
if (complexCondition) {
builder.age(age);
}
に
Integer age = null; // or whatever other default value you want
if (complexCondition) {
age = somethingElse;
}
Builder builder = Builder.name("name").id("id").age(age);
そして最後に、最初の4行をメソッドに抽出して年齢を計算し、年齢を返します。
Builder builder = Builder.name("name").id("id").age(computeAge());
私は個人的には次のようにインデントすることを好みます。これにより、IMOにより、読みやすくなり、デバッグが容易になります。
Builder builder = Builder.name("name")
.id("id")
.age(computeAge());
まあ、メソッド呼び出しごとに1つの引数が必要な場合は、
_Builder.name("name").id("id").age(age, complexCondition).build();
_
に
_Builder.name("name").id("id").age(age).ageCondition(complexCondition).build();
_
complexCondition
を_Predicate<Something>
_(ここでSomething
は条件の評価に使用されるあるタイプのインスタンスです)にすることを検討することをお勧めします。このように、Builder
のbuild()
を呼び出すと、年齢パラメーターが指定されている場合にのみ、複雑な条件が評価されます。
build
メソッドは次のようになります。
_public SomeClass build() {
SomeClass obj = new SomeClass();
obj.setName(name);
if (age != null && someCondition != null && someCondition.test(something)) {
obj.setAge(age);
}
return obj;
}
_
something
がどうなるかわかりません。それはあなたの複雑な状態の性質に依存します。
または、条件をオプションにする場合:
_public SomeClass build() {
SomeClass obj = new SomeClass();
obj.setName(name);
if (age != null) {
if (someCondition != null)) {
if (someCondition.test(something)) {
obj.setAge(age);
}
} else {
obj.setAge(age);
}
}
return obj;
}
_