ビルダーパターンと多数の必須パラメータ
質問
現在までに、私は に続く の実装を使用しています。 ここで ):
public class Widget {
public static class Builder {
public Builder(String name, double price) { ... }
public Widget build() { ... }
public Builder manufacturer(String value) { ... }
public Builder serialNumber(String value) { ... }
public Builder model(String value) { ... }
}
private Widget(Builder builder) { ... }
}
これは、私が遭遇した、さまざまな必須/必須およびオプションのパラメータを持つ複雑なオブジェクトを構築する必要があるほとんどの状況でうまく機能します。しかし、私は最近、すべてのパラメーターが必須である場合 (または少なくとも大部分が必須である場合) に、このパターンがどのような利益をもたらすかを理解するのに苦労しています。
これを回避する 1 つの方法は、渡されるパラメータを独自のクラスに論理的にグループ化し、ビルダー コンストラクターに渡されるパラメータの数を減らすことでした。
例えば、代わりに
Widget example = new Widget.Builder(req1, req2, req3,req4,req5,req6,req7,req8)
.addOptional(opt9)
.build();
は以下のようにグループ化されます。
Object1 group1 = new Object1(req1, req2, req3, req4);
Object2 group2 = new Object2(req5, req6);
Widget example2 = new Widget.Builder(group1, group2, req7, req8)
.addOptional(opt9)
.build();
別々のオブジェクトを持つことで物事はかなり単純化されますが、コードに慣れていない人には少し難しくもなります。私が考えたことのひとつは、すべてのパラメータを独自の
addParam(param)
メソッドに移し、必要なパラメータの検証を
build()
メソッドで必要なパラメータの検証を行います。
ベストプラクティスとは何でしょうか、また、私が考慮しなかったより良いアプローチがあるのでしょうか。
どのように解決するのですか?
しかし、私は最近、すべてのパラメータが必須である場合 (または少なくとも大多数が必須である場合)、このパターンがどのような利点があるのかを理解するのに苦労しています。
流暢なビルダーパターンはまだ有益です。
-
より読みやすい - 名前のついたパラメータを効果的に使用できるので、呼び出しが無名の引数の長いリストになることはありません。
-
順不同 - これは、単一のビルダーセッター呼び出しの一部として、または単に、この特定のインスタンス化の最も意味をなすビルダーセッターメソッドを呼び出すための自然な順序を使用させることによって、論理グループにまとめて引数をグループ化することができます。
Widget example = new Widget.Builder(req1, req2, req3,req4,req5,req6,req7,req8) .addOptional(opt9) .build();
は以下のようにグループ化されます。
Object1 group1 = new Object1(req1, req2, req3, req4); Object2 group2 = new Object2(req5, req6); Widget example2 = new Widget.Builder(group1, group2, req7, req8) .addOptional(opt9) .build();
別々のオブジェクトを持つことで物事はかなり単純化されますが、コードに慣れていない人には少し難しくもなります。私が考えたことのひとつは、すべてのパラメータを独自の
addParam(param)
メソッドに移し、必要なパラメータの検証をbuild()
メソッドで必要なパラメータの検証を行います。
私は、適切な場合や自然な場合には、ハイブリッドに賛成します。 すべてコンストラクタにある必要はありません。 または である必要はなく、それぞれのパラメータに独自のaddParamメソッドがあります。 Builderでは、どちらか一方、またはその中間、あるいは複合的な処理を柔軟に行うことができます。
Widget.Builder builder = new Widget.Builder(Widget.BUTTON); builder.withWidgetBackingService(url, resource, id); builder.withWidgetStyle(bgColor, lineWidth, fontStyle); builder.withMouseover("Not required"); Widget example = builder.build();
関連
-
[解決済み] JVM起動時のパラメータ「-Xms」「-Xmx」とは何ですか?
-
Javaでよくある構文エラー
-
maven レポート エラー 解決不可能な親POM
-
eclipse 実行 Java、エラー: 選択を起動できず、レシーバーもありません。
-
java 365*1000*60*60*24 計算問題
-
[解決済み] JavaにおけるHashMapとHashtableの違いは何ですか?
-
[解決済み] Javaにおけるpublic、protected、package-private、privateの違いは何ですか?
-
[解決済み] MVPとMVC、その違いは何ですか?
-
[解決済み] 静的クラスとシングルトンパターンの違い?
-
[解決済み] 引数とパラメータの違いは何ですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
XMLファイル操作時のjava.util.NoSuchElementExceptionを解決する方法。
-
アクセス制限です。タイプ 'JPEGCodec' は API ではない ☞My Blog Github ☜ ホームページを見る
-
Collections.sortがdoubleでソートできない問題を完璧に解決する。
-
Jsoup-Crawlingの動作
-
が 'X-Frame-Options' を 'sameorigin' に設定したため、フレーム内に存在する。
-
アノテーション「@Retention」の役割
-
API の戻り値を処理するために ResponseEntity を使用する
-
org.xml.sax.SAXParseExceptionのエラー解決方法
-
テストが空であるかどうかを判断するためのオプションの処理
-
linux ant Resolve error: main class not found or couldn't be loaded org.apache.tools.ant.launcher.