プレビュー記事: 初心者のための Java デザインパターンに関するメモ - BUILDER パターン

 

ビルダー (BUILDER) モードはジェネレーター (BUILDER) モードとも呼ばれます。その定義は次のとおりです (GoF のデザイン パターンと Yan Hon の「Java とパターン」を参照)

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

 

2. 参加者:

• 抽象ビルダー (Builder):製品 (Prodcut)オブジェクトを作成する各コンポーネントの抽象インターフェイスを指定します。
• コンクリートビルダー (ConcretBuilder):

抽象ビルダー (Builder)インターフェイス    を実装して、製品のさまざまなコンポーネントを構築およびアセンブルします。
    それが作成する表現を定義して明確にします。
    製品を取得するためのインターフェイスを提供します。

• Director:抽象的な Builderインターフェイスを使用してオブジェクトを構築します
• 製品(製品):

  構築された複雑なオブジェクトを表します。コンクリート ビルダー (ConcretBuilder) は、製品の内部表現を作成し、その組み立てプロセスを定義します。
  コンポーネント部分を定義するクラスが含まれており、これらの部分を最終製品に組み立てるインターフェイスも含まれます。

 

3. 構造:



 

GoF の設計パターンに従って、BUILDER パターンを使用するときのさまざまな役割間の協力関係を説明してみましょう。

1. クライアントはDirectorオブジェクトを作成し、それを必要な抽象 Builder の ConcretBuilder オブジェクトで構成します。
2. 製品の特定のコンポーネント (PartOne、PartTwo、...) を作成する必要がある場合、ディレクター (Director) は特定のビルダー (ConcretBuilder)に通知します
3.特定のビルダー (ConcretBuilder) がディレクターの要求を処理し、パーツ (PartOne、PartTwo、...) をプロダクト (Prodcut)に追加します。
4. クライアントは、コンクリート ビルダー (ConcretBuilder)から製品 (Prodcut)を取得します

 

===============間奏===============================

「再利用可能なオブジェクト指向ソフトウェアのためのデザイン パターンの基礎」(GOF デザイン パターン中国語版) を参照する場合、 Builder パターンのコラボレーションに関する 2 番目の説明が理解できません。

製品部分が生成されると、ディレクタはジェネレータに通知します。(中国語の Wikipedia を確認してください。このように翻訳されています)

英語の原著と比較すると次のように説明されています。

Director は、製品の一部をビルドする必要があるたびに、ビルダーに通知します。

 

では、以下のような意味に訳すべきでしょうか?

ディレクターは、製品のコンポーネントを作成する必要があるとき (作成する必要があるとき) をジェネレーターに通知します。

(言い換えれば、製品部分を生成する必要があると、ディレクタはジェネレータに通知します。 )

  

ちょっと真面目すぎるかもしれませんが、個人的には前者と前者の二つの中国語表現は意味が違うはずだと思っています。

================================================= ===

 

 

実際の例に基づいてビルダー パターンを理解します自動車生産を例に挙げてみましょう。例9

顧客は一汽フォルクスワーゲン車の購入を希望しています。

自動車は実際には製品ファミリー、つまり自動車部品製品 (製品ファミリー) のセット (シリーズ) です。

車の構造は非常に複雑です。ホイール、ハンドル、シート、エンジン、色などがあります。

 

この例がなぜとても見慣れたものに見えるのでしょうか?

1. これは前の記事「初心者のための Java デザイン パターンに関するメモ - 抽象ファクトリ パターン」と非常に似ているようです。

どちらも複雑なオブジェクト (製品コレクションまたは製品ファミリー) を作成できます。

GoF のデザイン パターンには次のようなものがあります。

Abstract Factory は、複雑なオブジェクトも作成できるという点で Builder に似ています。主な違いは、Builder パターンが複雑なオブジェクトを段階的に構築することに焦点を当てていることです。Abstract Factory は、複数のシリーズの製品オブジェクト (単純または複雑) に焦点を当てています。

 

言い換えれば、Builder パターンは、複雑な製品のさまざまなコンポーネント (またはコンポーネント製品) を組み立てる方法に関係します。

Abstract Factory モデルは、どのコンポーネント (またはコンポーネント製品) が組み立てられるかに関係します。

 

2. これは、初心者向けの Java 設計パターンに関する以前の別のメモ - Factory Patternと非常に似ているようです

ファクトリ パターンの利点を確認し、ビルダー パターンの目的と比較します。

ファクトリ パターンを使用すると、オブジェクトの作成プロセスと使用を分離する (つまり、切り離す) ことができます。

ビルダー パターンは、複雑なオブジェクトの構築をその表現から分離し、同じ構築プロセスで異なる表現を作成できるようにします。

個人的に私は思います、

ビルダー パターンは、規則的または秩序ある作成 (構築) プロセスに重点を置いています。

ファクトリーパターンの作成(構築)プロセスは比較的カジュアルです。

  

 

実際、factorybuilderという 2 つの名前からもその違いを理解することができます。

ビルダーは工場の生産設備似ています。 

工場はどのような製品を生産するかだけを気にしており、その製品が何でできているかだけを知っています。

作り手は製品をどのように生産するかを考える必要があり、製品の構成ルールや方法を考慮する必要があります。

 

言い換えれば、ビルダー パターンは、ある程度、ファクトリ パターン内のファクトリ ロールの責任の一部を改良した ようなものです。

ディレクターは製品の制作を指導しビルダーは具体的な制作を実装します。

 

この例を続けて、ビルダー パターンを体験します。

 

抽象ビルダー: 

 

/*
 * 建造者 
 */
public interface CarBuilder {
	
	/**
	 * 建造汽车的框架
	 */
	public void buildeCarSkeleton();
	
	/**
	 * 给汽车装上发动机
	 */
	public void buildeCarEngine();
	
	/**
	 * 给汽车装上轮子
	 */
	public void buildeCarWheels();
	
	/**
	 * 给汽车装上导航设备
	 */
	public void buildeCarNavigation();
	
	/**
	 * 安装车身(包含车门、车窗的安装,涂颜色)
	 */
	public void buildeCarBody();

}

 

特定のビルダー:(アウディ A6 を生産)

  

監督: 

ここで、ディレクターはビルダーに、ある方法で車を製作するように指示します(ナビゲーション システムが取り付けられている)。

 

/*
 * 导演者
 */
public class AudiDirector {
	
	CarBuilder builder;

	/**
	 * 为导演者配置一个建造者
	 */
	public AudiDirector(CarBuilder builder){
		this.builder = builder;
		
	}

	/**
	 * 按照一定的方式或规则建造汽车
	 */
	public void contruct(){
		
		builder.buildeCarSkeleton();
		
		builder.buildeCarEngine();
		
		builder.buildeCarNavigation();
		
		builder.buildeCarWheels();
		
		builder.buildeCarBody();
		
	}
}

 

アウディ車(製品): 

 

/*
 * 产品
 */
public class AudiCar {
	
	private String carSkeleton;
	private Engine carEngine;
	private String carWheels;
	private String carNavigation = "";
	
	private String carDoor;
	private String carWindscreen;
	private String carColor;
	
	public AudiCar(){	}
	
	/**
	 * 汽车的颜色
	 */
	public void setCarColor(String carColor) {
		this.carColor = carColor;
	}
	/**
	 * 汽车的车门
	 */
	public void setCarDoor(String carDoor) {
		this.carDoor = carDoor;
	}
	/**
	 * 汽车发动机,发动机在这里是一个对象
	 */
	public void setCarEngine(Engine carEngine) {
		this.carEngine = carEngine;
	}
	/**
	 * 汽车的框架
	 */
	public void setCarSkeleton(String carSkeleton) {
		this.carSkeleton = carSkeleton;
	}
	/**
	 * 汽车轮子
	 */
	public void setCarWheels(String carWheels) {
		this.carWheels = carWheels;
	}
	/**
	 * 汽车的挡风玻璃
	 */
	public void setCarWindscreen(String carWindscreen) {
		this.carWindscreen = carWindscreen;
	}
	/**
	 * 汽车导航
	 */
	public void setNavigation(String navigation) {
		this.carNavigation = navigation;
	}
	

	/**
	 * 一个汽车对象的描述
	 */
	public String toString(){
		return carSkeleton+ "," + carEngine.toString() +"," + carWheels + "," +
		carDoor + "," + carWindscreen + "," + carColor + "," + carNavigation;
	}
}

 

車のコンポーネント オブジェクト:

 

/*
 * 一个部件对象(汽车发动机)
 */
public class Engine {
	
	private String name;
	
	public Engine(String name){
		this.name = name;
	}
	
	public String toString(){
		return this.name;
	}

}

 

クライアント:

 

/*
 * 客户端
 */
public class Clients {

	public static void main(String[] args) {
		
//		创建一个建造者对象
		AudiCarBuilder builder = new AudiCarBuilder();
		
//		创建一个导演者,并为它配置一个建造者
		AudiDirector director1 = new AudiDirector(builder);
		
//		导演者将通知建造者去创建产品
//		在这个过程中,建造者将会根据导演者的请求,去创建组织并创建产品对象
		director1.contruct();
		
//		从具体建造者中检索产品(返回的是带导航的汽车产品)。
		AudiCar audiCar = builder.retrieveCar();
		
		System.out.println(audiCar);	
	}
}

 

操作結果:

汽车框架,奥迪A6发动机,车轮,车门,挡风玻璃,黑色,汽车导航

 

ナビゲーション システムのないアウディ A6 車を生産したい場合、どうすれば実現できますか?

ディレクターを変更するだけです。

新しいディレクター: (ナビゲーション システムをインストールしないようにビルダーに指示します)

 

/*
 * 导演者
 */
public class AudiDirector {
	
	CarBuilder builder;

	/**
	 * 为导演者配置一个建造者
	 */
	public AudiDirector(CarBuilder builder){
		this.builder = builder;
		
	}

	/**
	 * 按照一定的方式或规则建造汽车
	 */
	public void contruct(){
		
		builder.buildeCarSkeleton();
		
		builder.buildeCarEngine();
		
//		不安装导航系统
//		builder.buildeCarNavigation();
		
		builder.buildeCarWheels();
		
		builder.buildeCarBody();
		
	}
}

 

走行結果:(ナビなし

 

  

汽车框架,奥迪A6发动机,车轮,车门,挡风玻璃,黑色,

 

 

 

 ナビゲーション システムを搭載したアウディ A8 車を生産したい場合、どうすれば実現できますか?

(アウディ A6 とアウディ A8 の唯一の違いはエンジンであると仮定します)

ビルダークラスを変更するだけです

 

ビルダー: (独自の内部実装を変更するだけです- Audi A6 エンジンをAudi A8 エンジン変更します)

 

/*
 * 具体建造者
 */
public class AudiCarBuilder implements CarBuilder {
	
	private AudiCar audiCar = new AudiCar();

	/**
	 * 安装车身(包含车门、车窗的安装,涂颜色)
	 */
	public void buildeCarBody() {
		audiCar.setCarDoor("车门");
		audiCar.setCarWindscreen("挡风玻璃");
		audiCar.setCarColor("黑色");
	}

	/**
	 * 给汽车装上发动机
	 */
	public void buildeCarEngine() {
		Engine audiEngine = new Engine("奥迪A8发动机");
		audiCar.setCarEngine(audiEngine);
	}

	/**
	 * 给汽车装上导航设备
	 */
	public void buildeCarNavigation() {
		audiCar.setNavigation("汽车导航");
	}

	/**
	 * 建造汽车的框架
	 */
	public void buildeCarSkeleton() {
		audiCar.setCarSkeleton("汽车框架");
	}

	/**
	 * 给汽车装上轮子
	 */
	public void buildeCarWheels() {
		audiCar.setCarWheels("车轮");
	}
	
	public AudiCar retrieveCar(){
		return audiCar;
	}

}

 

 

走行結果:(アウディA8エンジンに換装

汽车框架,奥迪A8发动机,车轮,车门,挡风玻璃,黑色,汽车导航

  

 

この例から、ビルダー パターンの利点がわかります。

1.ディレクターはさまざまな生産方法 (ナビゲーションを取り付けるかどうか) を指定でき、ビルダーは変更を加えずにさまざまな製品を入手できます。

2.ディレクターは希望する生産方法を変更する必要はなく、ビルダーは内部実装 (どの種類のエンジンを選択するか) を変更するだけで済み、異なる製品を入手することもできます。

  

ビルダー モードの効果の詳細については、GoF の「デザイン パターン」を参照してください。

/*
 * 具体建造者
 */
public class AudiCarBuilder implements CarBuilder {
	
	private AudiCar audiCar = new AudiCar();

	/**
	 * 安装车身(包含车门、车窗的安装,涂颜色)
	 */
	public void buildeCarBody() {
		audiCar.setCarDoor("车门");
		audiCar.setCarWindscreen("挡风玻璃");
		audiCar.setCarColor("黑色");
	}

	/**
	 * 给汽车装上发动机
	 */
	public void buildeCarEngine() {
		Engine audiEngine = new Engine("奥迪A6发动机");
		audiCar.setCarEngine(audiEngine);
	}

	/**
	 * 给汽车装上导航设备
	 */
	public void buildeCarNavigation() {
		audiCar.setNavigation("汽车导航");
	}

	/**
	 * 建造汽车的框架
	 */
	public void buildeCarSkeleton() {
		audiCar.setCarSkeleton("汽车框架");
	}

	/**
	 * 给汽车装上轮子
	 */
	public void buildeCarWheels() {
		audiCar.setCarWheels("车轮");
	}
	
	public AudiCar retrieveCar(){
		return audiCar;
	}

}

 

おすすめ

転載: blog.csdn.net/louis_lee7812/article/details/83772087
おすすめ