DesignPattern - 建造者模式【建立型】

歡迎關注微信公衆號:FSA全棧行動 👋java

1、建造者模式介紹

建造者模式(Builder Pattern)使用多個簡單的步驟一步步構建成一個複雜的對象,將一個複雜對象的構建與它的表示分離,使得一樣的構建過程能夠建立出不一樣的實例;容許用戶只經過指定複雜對象的類型和內容就能夠構建它們,不須要知道內部的具體構建細節。編程

  • 核心組成微信

    • Product:產品角色markdown

    • Builder:抽象建造者,定義多個通用方法和構建方法ide

    • ConcreteBuilder:具體建造者,能夠有多個oop

    • Director:指揮者,控制整個組合過程,將需求交給建造者,由建造者去建立對象ui

      補充:核心組成不必定要所有齊全,好比 Director 一般能夠省略,可參考 java 中的 StringBuilder 也是建造者模式(不徹底同樣,但思想一致)this

  • 場景舉例spa

    • KFC 建立套餐:套餐是一個複雜對象,它通常包含 主食如漢堡、烤翅 和 飲料若是汁、可樂等 組成部分,不一樣的套餐有不一樣的組合,而 KFC 的服務員能夠根據顧客的要求,一步一步裝配這些組成部分,構造一份完整的套餐
    • 電腦組裝:有低配、高配,根據用戶需求,採購不一樣規格的 CPU、內存、電源、硬盤、主板等。
  • 優勢code

    • 客戶端沒必要知道產品內部組成的細節,將產品自己與產品的建立過程解耦
    • 每個具體建造者都相對獨立,而與其餘的具體建造者無關,更加精細地控制產品的建立過程
    • 增長新的具體建造者無須修改原有類庫的代碼,符合開閉原則
    • 建造者模式結合鏈式編程來使用,代碼上更加美觀
  • 缺點

    • 建造者模式所建立的產品通常具備較多的共同點,若是產品差別大則不建議使用
  • 建造者模式與抽象工廠模式的比較:

    • 建造者模式返回一個組裝好的完整產品
    • 抽象工廠模式返回一系列相關的產品,這些產品位於不一樣的產品等級結構,構成一個產品族

2、建造者模式代碼實現

建立產品類:

/** * 套餐 * * @author GitLqr */
public class SetMenu {
	// 主食
	private String stapleFood;

	// 飲料
	private String drink;

	// 小吃
	private String snack;

	public SetMenu(String stapleFood, String drink, String snack) {
		super();
		this.stapleFood = stapleFood;
		this.drink = drink;
		this.snack = snack;
	}

	@Override
	public String toString() {
		return "SetMenu [stapleFood=" + stapleFood + ", drink=" + drink + ", snack=" + snack + "]";
	}

}
複製代碼

建立抽象建造者類(或接口):

/** * 套餐建造接口 * * @author GitLqr */
public interface ISetMenuBuilder {
	ISetMenuBuilder addStapleFood(String stapleFood);

	ISetMenuBuilder addDrink(String drinkString);

	ISetMenuBuilder addSnak(String snak);

	SetMenu build();
}
複製代碼

建立具體建造者類:

/** * KFC 套餐建造器 * * @author GitLqr */
public class KFCSetMenuBuilder implements ISetMenuBuilder {

	private List<String> stapleFoods = new ArrayList<>();
	private List<String> drinks = new ArrayList<>();
	private List<String> snaks = new ArrayList<>();

	@Override
	public ISetMenuBuilder addStapleFood(String stapleFood) {
		this.stapleFoods.add(stapleFood);
		return this;
	}

	@Override
	public ISetMenuBuilder addDrink(String drink) {
		this.drinks.add(drink);
		return this;
	}

	@Override
	public ISetMenuBuilder addSnak(String snak) {
		this.snaks.add(snak);
		return this;
	}

	@Override
	public SetMenu build() {
		return new SetMenu(stapleFoods.toString(), drinks.toString(), snaks.toString());
	}

}
複製代碼

說明:【具體建造者類】能夠拓展出不少個,好比 "永和豆漿" 的套餐建造者 YonHoSetMenuBuilder 等等。

建立指揮者類(Director):

/** * KFC 指揮者(服務員) * * @author GitLqr */
public class KFCDirector {

	public static SetMenu getBreakfastSetMenu() {
		return new KFCSetMenuBuilder()
				.addStapleFood("皮蛋瘦肉粥")
				.addDrink("豆漿")
				.build();
	}

	public static SetMenu getFamilyBucketSetMenu() {
		return new KFCSetMenuBuilder()
				.addStapleFood("香辣雞腿堡")
				.addStapleFood("新奧爾良烤雞腿堡")
				.addDrink("百事可樂")
				.addDrink("美年達")
				.addSnak("吮指原味雞")
				.addSnak("新奧爾良烤翅")
				.addSnak("葡式蛋撻")
				.addSnak("醇香土豆泥")
				.build();
	}
}
複製代碼

說明:實際開發中,指揮者類(Director)不少時候會被省略掉,取而代之,由使用者在業務代碼中 使用【具體建造者類】直接建立產品,這讓產品的建立更加靈活,但同時也增長了不可控性,需根據實際狀況權衡利弊。

使用:

public class Test {
	public static void main(String[] args) {
		SetMenu breakfast = KFCDirector.getBreakfastSetMenu();
		SetMenu familyBucket = KFCDirector.getFamilyBucketSetMenu();
		System.out.println("KFC早餐套餐:" + breakfast);
		System.out.println("KFC全家桶套餐:" + familyBucket);
	}
}
複製代碼

若是文章對您有所幫助, 請不吝點擊關注一下個人微信公衆號:FSA全棧行動, 這將是對我最大的激勵. 公衆號不只有Android技術, 還有iOS, Python等文章, 可能有你想要了解的技能知識點哦~

相關文章
相關標籤/搜索