技術共有

デザインパターンビルダーパターン

2024-07-12

한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina

デザイン パターンのビルダー パターンは、一般的に使用されるオブジェクト作成デザイン パターンであり、主に複雑なオブジェクト構築の問題を解決するために使用されます。ここではビルダー モードの詳細を紹介します。

1. 定義

ビルダー パターンは、複雑なオブジェクトの構築をその表現から分離し、同じ構築プロセスで異なる表現を作成できるようにします。言い換えれば、複雑なオブジェクトの構築プロセスを一連の単純なステップに分割し、ユーザーがこれらのステップの順序とパラメータを指定することでさまざまなオブジェクトを作成できるようにすることで機能します。

2. クラス図と構造

クラス図

ビルダー モードには通常、次のロールが含まれます。

  1. 製品の役割(製品): 構築中の複雑なオブジェクトを表し、通常は複数のコンポーネントが含まれます。
  2. 抽象ビルダー: 製品オブジェクトのさまざまなコンポーネントを作成するための抽象インターフェイスを定義します。
  3. コンクリートビルダー: Builder インターフェイスを実装し、複雑な製品の各コンポーネントの特定の作成メソッドを完了し、最終製品を返すインターフェイスを定義します。
  4. 監督 : ビルダー オブジェクト内のコンポーネント構築メソッドとアセンブリ メソッドを呼び出して、複雑なオブジェクトの作成を完了します。これには製品固有の情報は含まれませんが、クライアントをビルダーから切り離すだけです。

3. 適用可能なシナリオ

ビルダー パターンは次のシナリオに適しています。

  1. オブジェクトの構造が複雑です: 構築する必要があるオブジェクトの内部構造が複雑で、複数のプロパティとメソッドが含まれている場合、ビルダー パターンを使用すると構築プロセスを簡素化できます。
  2. 構築プロセスは複雑です: オブジェクトの構築プロセスに複数のステップが含まれており、これらのステップの順序とパラメータが異なる場合、ビルダー パターンは明確な構築プロセスを提供できます。
  3. 分離された作成と使用: オブジェクトの作成プロセスと使用プロセスを分離して、ユーザーがオブジェクトの最終的な表現のみに注意すればよく、オブジェクト作成の詳細は気にする必要がないようにしたい場合、ビルダー パターンは良い選択です。

4. メリットとデメリット

アドバンテージ
  1. 良好なカプセル化: ビルダー内で複雑なオブジェクトの構築プロセスをカプセル化します。クライアントは構築プロセスの詳細を知らなくても、構築のタイプとパラメータを指定するだけで最終製品を取得できます。
  2. 優れた拡張性注: 新しいビルド タイプを追加するか、ビルド プロセスを変更する必要がある場合は、ビルダー クラスを追加または変更するだけでよく、クライアント コードには影響しません。
  3. 高い柔軟性: ビルダーのビルド順序またはパラメーターを変更することで、さまざまな製品インスタンスを作成できる柔軟性。
欠点がある
  1. クラス数を増やす: ビルダー インターフェイス、特定のビルダー クラス、コマンダー クラスなどの複数のクラスを作成する必要があるため、システム内のクラスの数が増加する可能性があります。
  2. 内部改造の難しさ: 製品の内部構造が変更された場合、複数のビルダー クラスの変更が必要になる可能性があり、システムの保守コストが増加します。

5. 例

次の例では、Builder パターンを使用して住宅改修システムを設計します。を定義します。Houseクラスは、複数の装飾コンポーネント (天井、ペイント、床、床タイルなど) を含む複雑なオブジェクトです。次に、HouseBuilderこれらのコンポーネントを作成するための抽象メソッドを含むインターフェイス。次に、特定の装飾スタイル (豪華なヨーロピアン スタイル、ライトで豪華な田園スタイル、モダンなミニマリストなど) ごとに特定のビルダー クラスを作成します。最後に、Directorクラスを使用して構築プロセスをガイドしますが、完全な構築ロジックをビルダー クラスで直接定義できるため、この例では必要ない場合があります。

ただし、指揮者の役割の概念を示すために、Directorクラスを使用していますが、これは説明のみを目的としており、実際には、ビルド プロセスはビルダー クラスで直接実行できます。

  1. // 房屋类
  2. public class House {
  3. private String ceiling; // 吊顶
  4. private String paint; // 涂料
  5. private String floor; // 地板
  6. private String tiles; // 地砖
  7. // 私有构造函数
  8. private House() {}
  9. // Getter 方法
  10. public String getCeiling() {
  11. return ceiling;
  12. }
  13. public String getPaint() {
  14. return paint;
  15. }
  16. public String getFloor() {
  17. return floor;
  18. }
  19. public String getTiles() {
  20. return tiles;
  21. }
  22. // 建造者接口
  23. public interface HouseBuilder {
  24. HouseBuilder buildCeiling(String ceiling);
  25. HouseBuilder buildPaint(String paint);
  26. HouseBuilder buildFloor(String floor);
  27. HouseBuilder buildTiles(String tiles);
  28. House build();
  29. }
  30. // 豪华欧式建造者 ,注意是静态内部类
  31. public static class LuxuryEuropeanBuilder implements HouseBuilder {
  32. private House house;
  33. public LuxuryEuropeanBuilder() {
  34. this.house = new House();
  35. }
  36. @Override
  37. public HouseBuilder buildCeiling(String ceiling) {
  38. house.ceiling = "豪华欧式吊顶: " + ceiling;
  39. return this;
  40. }
  41. @Override
  42. public HouseBuilder buildPaint(String paint) {
  43. house.paint = "豪华欧式涂料: " + paint;
  44. return this;
  45. }
  46. @Override
  47. public HouseBuilder buildFloor(String floor) {
  48. house.floor = "豪华欧式地板: " + floor;
  49. return this;
  50. }
  51. @Override
  52. public HouseBuilder buildTiles(String tiles) {
  53. house.tiles = "豪华欧式地砖: " + tiles;
  54. return this;
  55. }
  56. @Override
  57. public House build() {
  58. return house;
  59. }
  60. }
  61. // ... 可以为其他风格创建类似的建造者类
  62. // 指挥者类(可选,这里主要用于展示概念)
  63. public static class Director {
  64. private HouseBuilder builder;
  65. public Director(HouseBuilder builder) {
  66. this.builder = builder;
  67. }
  68. // 这里可以添加方法来指导建造过程,但在这个例子中,我们直接在建造者中完成了所有工作
  69. public House constructHouse() {
  70. // 假设这是由指挥者指导的步骤,但在这里我们直接返回建造者的结果
  71. return builder
  72. .buildCeiling("水晶吊灯")
  73. .buildPaint("金色镶边涂料")
  74. .buildFloor("大理石地板")
  75. .buildTiles("马赛克地砖")
  76. .build();
  77. }
  78. }
  79. // 主函数,用于演示
  80. public static void main(String[] args) {
  81. HouseBuilder luxuryBuilder = new LuxuryEuropeanBuilder();
  82. // Director director = new Director(luxuryBuilder); // 如果使用指挥者
  83. House house = luxuryBuilder
  84. .buildCeiling("水晶吊灯")
  85. .buildPaint("金色镶边涂料")
  86. .buildFloor("大理石地板")
  87. .buildTiles("马赛克地砖")
  88. .build();
  89. System.out.println("Ceiling: " + house.getCeiling());
  90. System.out.println("Paint: " + house.getPaint());
  91. System.out.println("Floor: " + house.getFloor());
  92. System.out.println("Tiles: " + house.getTiles());
  93. }
  94. }

この例では、Directorすべてのビルド ロジックはすでにカプセル化されているため、クラスは実際には大きな価値を追加しません。HouseBuilderインターフェースが実装されています。しかし、より複雑なアプリケーションでは、Director特にビルド プロセスが複数のビルダーにまたがる場合、クラスを使用してビルド プロセスの順序とロジックをカプセル化できます。

6. 結論

上記の紹介から、ビルダー パターンは、複雑なオブジェクトを構築するときに、構築プロセスを表現から分離することでコードのカプセル化とスケーラビリティを向上させ、クライアントと特定のオブジェクト間の通信も削減するという大きな利点があることがわかります。間の結合度。

この記事があなたの研究に役立つ場合は、「いいね」を押して収集してください。