ビルダーパターン


ビルダー パターンは、複数の単純なオブジェクトを使用して、複雑なオブジェクトを段階的に構築します。このタイプのデザイン パターンは創造的なパターンであり、オブジェクトを作成するための最適な方法を提供します。

Builder クラスは、最終的なオブジェクトを段階的に構築します。 Builder クラスは他のオブジェクトから独立しています。

はじめに

目的: 同じ構築プロセスで異なる表現を作成できるように、複雑な構築をその表現から分離します。

主な解決策: 主な解決策: ソフトウェア システムでは、要件の変更により、通常、特定のアルゴリズムを使用して各部分のサブオブジェクトで構成される「複雑なオブジェクト」の作成に直面することがあります。この複雑なオブジェクトの複雑さ 個々の部分はしばしば劇的な変化に直面しますが、それらを統合するアルゴリズムは比較的安定しています。

いつ使用するか: 一部の基本コンポーネントは変更されないが、その組み合わせが頻繁に変更される場合。

解決方法: 変更を不変性から分離します。

キーコード: Builder: インスタンスを作成して提供し、director: 構築されたインスタンスの依存関係を管理します。

応用例: 1. KFC に行くと、ハンバーガー、コーラ、フライドポテト、手羽先の唐揚げなどは同じですが、その組み合わせが頻繁に変わり、いわゆる「定食」が生成されます。 2. JAVA の StringBuilder。

利点: 1. ビルダーは独立しており、拡張が簡単です。 2. 細かなリスクを容易に管理。

短所: 1. 製品には共通点が必要であり、範囲は限られています。 2. 内部変更が複雑な場合、多くの構築クラスが存在します。

使用シナリオ: 1. 生成する必要があるオブジェクトは複雑な内部構造を持っています。 2. 生成する必要があるオブジェクトの内部プロパティは相互依存しています。

注: ファクトリーモードとの違いは、ビルダーモードではパーツの組み立て順序により注意が払われることです。

実装

ここでは、典型的なセットメニューがハンバーガー (Burger) とコールドドリンク (Cold Drink) であるファーストフードレストランのビジネスケースを想定しています。バーガーにはベジタリアンバーガーまたはチキンバーガーがあり、カートンに詰められています。冷たい飲み物はボトルに入ったコーラやペプシです。

食品 (ハンバーガーや冷たい飲み物など) を表す Item インターフェースと Item インターフェースを実装するエンティティ クラス、および Packing インターフェースを実装する Packing インターフェースとエンティティ クラスを作成します。食品の包装を表し、ハンバーガーは紙パックで提供され、冷たい飲み物はボトルで提供されます。

次に、ItemArrayListを持つMealクラスと、Itemを組み合わせてさまざまなタイプのMealオブジェクトを作成するMealBuilderを作成します。 BuilderPatternDemo、私たちのデモクラスはMealBuilderを使用して食事を作成します。

builder_pattern_uml_diagram.jpg

ステップ 1

食品と食品のパッケージを表すインターフェイスを作成します。

Item.java

public interface Item {
   public String name();
   public Packing packing();
   public float price();	
}

Packing.java

public interface Packing {
   public String pack();
}

ステップ 2

Packing インターフェイスを実装するエンティティ クラスを作成します。

Wrapper.java

public class Wrapper implements Packing {

   @Override
   public String pack() {
      return "Wrapper";
   }
}

Bottle.java

public class Bottle implements Packing {

   @Override
   public String pack() {
      return "Bottle";
   }
}

ステップ 3

デフォルトの機能を提供する、Item インターフェイスを実装する抽象クラスを作成します。

Burger.java

public abstract class Burger implements Item {

   @Override
   public Packing packing() {
      return new Wrapper();
   }

   @Override
   public abstract float price();
}

ColdDrink.java

public abstract class ColdDrink implements Item {

	@Override
	public Packing packing() {
       return new Bottle();
	}

	@Override
	public abstract float price();
}

ステップ 4

Burger と ColdDrink を拡張するエンティティ クラスを作成します。

VegBurger.java

public class VegBurger extends Burger {

   @Override
   public float price() {
      return 25.0f;
   }

   @Override
   public String name() {
      return "Veg Burger";
   }
}

ChickenBurger.java

public class ChickenBurger extends Burger {

   @Override
   public float price() {
      return 50.5f;
   }

   @Override
   public String name() {
      return "Chicken Burger";
   }
}

Coke.java

public class Coke extends ColdDrink {

   @Override
   public float price() {
      return 30.0f;
   }

   @Override
   public String name() {
      return "Coke";
   }
}

Pepsi.java

public class Pepsi extends ColdDrink {

   @Override
   public float price() {
      return 35.0f;
   }

   @Override
   public String name() {
      return "Pepsi";
   }
}

ステップ5

食事を作成するクラス、上で定義したItemオブジェクトを使用します。

Meal.java

import java.util.ArrayList;
import java.util.List;

public class Meal {
   private List<Item> items = new ArrayList<Item>();	

   public void addItem(Item item){
      items.add(item);
   }

   public float getCost(){
      float cost = 0.0f;
      for (Item item : items) {
         cost += item.price();
      }		
      return cost;
   }

   public void showItems(){
      for (Item item : items) {
         System.out.print("Item : "+item.name());
         System.out.print(", Packing : "+item.packing().pack());
         System.out.println(", Price : "+item.price());
      }		
   }	
}

ステップ 6

MealBuilder クラスを作成します。実際のビルダー クラスは、Meal オブジェクトの作成を担当します。

MealBuilder.java

public class MealBuilder {

   public Meal prepareVegMeal (){
      Meal meal = new Meal();
      meal.addItem(new VegBurger());
      meal.addItem(new Coke());
      return meal;
   }   

   public Meal prepareNonVegMeal (){
      Meal meal = new Meal();
      meal.addItem(new ChickenBurger());
      meal.addItem(new Pepsi());
      return meal;
   }
}

ステップ 7

BuiderPatternDemo MealBuider を使用して、ビルダー パターンをデモンストレーションします。

BuilderPatternDemo.java

public class BuilderPatternDemo {
   public static void main(String[] args) {
      MealBuilder mealBuilder = new MealBuilder();

      Meal vegMeal = mealBuilder.prepareVegMeal();
      System.out.println("Veg Meal");
      vegMeal.showItems();
      System.out.println("Total Cost: " +vegMeal.getCost());

      Meal nonVegMeal = mealBuilder.prepareNonVegMeal();
      System.out.println("\n\nNon-Veg Meal");
      nonVegMeal.showItems();
      System.out.println("Total Cost: " +nonVegMeal.getCost());
   }
}

ステップ 8

出力を確認します。

りー