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等文章, 可能有你想要了解的技能知识点哦~

相关文章
相关标签/搜索