建造者模式
建造者模式,又称生成器模式:将一个复杂的构建与其表示相分离,使得同样的构建过程可以创建不同的表示。
三个角色:建造者、具体的建造者、监工、使用者(严格来说不算)
- 建造者角色:定义生成实例所需要的所有方法;
- 具体的建造者角色:实现生成实例所需要的所有方法,并且定义获取最终生成实例的方法;
- 监工角色:定义使用建造者角色中的方法来生成实例的方法;
- 使用者:使用建造者模式。
示例
一般来说,去快餐店点单的时候,一个套餐可能会有很多的选择,可以只需要基础的汉堡和饮料,也可以增加一些别的东西。如果定义一个套餐对象,其属性包含必须的汉堡和饮料,也包含可能会用到更多的食品:烤翅、圣代、蛋挞、薯条等甜点和小食以及配餐。如果统一使用构造方法来创建的话,则会有很多的构造方法添加在套餐对象中,而且,每增加一种新的食品种类时,基本上得增加n种构造方法。如果使用set方法的话,每一次都得增加新的set方法。建造者模式就是为了解决这一问题的。
食物总接口
package com.designpattern.builder;
public interface Food {
String toString();
}
汉堡
package com.designpattern.builder.hamburger;
import com.designpattern.builder.Food;
public abstract class Hamburger implements Food {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Hamburger = " + getName() + ";";
}
}
牛肉汉堡
package com.designpattern.builder.hamburger;
public class BeefHamburger extends Hamburger{
public BeefHamburger() {
setName("BeefHamburger");
}
}
猪肉汉堡
package com.designpattern.builder.hamburger;
public class PorkHamburger extends Hamburger {
public PorkHamburger() {
setName("PorkHamburger");
}
}
鸡肉汉堡
package com.designpattern.builder.hamburger;
public class ChickenHamburger extends Hamburger {
public ChickenHamburger() {
setName("ChickenHamburger");
}
}
饮料
package com.designpattern.builder.drink;
import com.designpattern.builder.Food;
public abstract class Drink implements Food {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Drink = " + getName() + ";";
}
}
百事可乐
package com.designpattern.builder.drink;
public class PepsiCola extends Drink {
public PepsiCola() {
setName("Pepsi Cola");
}
}
可口可乐
package com.designpattern.builder.drink;
public class CocaCola extends Drink {
public CocaCola() {
setName("Coca Cola");
}
}
哇哈哈
package com.designpattern.builder.drink;
public class Wahaha extends Drink{
public Wahaha() {
setName("Wahaha");
}
}
甜点
package com.designpattern.builder.dessert;
import com.designpattern.builder.Food;
public abstract class Dessert implements Food {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Dessert = " + getName() + ";";
}
}
冰激凌
package com.designpattern.builder.dessert;
public class IceCream extends Dessert{
public IceCream() {
setName("IceCream");
}
}
布丁
package com.designpattern.builder.dessert;
public class Pudding extends Dessert {
public Pudding() {
setName("Pudding");
}
}
圣代
package com.designpattern.builder.dessert;
public class Sundae extends Dessert {
public Sundae() {
setName("Sundae");
}
}
沙拉
package com.designpattern.builder.salad;
import com.designpattern.builder.Food;
public abstract class Salad implements Food {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Salad = " + getName() + ";";
}
}
蔬菜沙拉
package com.designpattern.builder.salad;
public class VegetableSalad extends Salad{
public VegetableSalad() {
setName("Vegetable salad");
}
}
水果沙拉
package com.designpattern.builder.salad;
public class FruitSalad extends Salad {
public FruitSalad() {
setName("Fruit Salad");
}
}
小食
package com.designpattern.builder.snack;
import com.designpattern.builder.Food;
public abstract class Snack implements Food {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Snack = " + getName() + ";";
}
}
薯条
package com.designpattern.builder.snack;
public class FrenchFries extends Snack {
public FrenchFries() {
setName("French Fries");
}
}
炸鸡块
package com.designpattern.builder.snack;
public class ChickenNuggets extends Snack{
public ChickenNuggets() {
setName("Chicken Nuggets");
}
}
顾客
package com.designpattern.builder;
public class Customer {
private String name;
public Customer(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
快餐店
package com.designpattern.builder;
import com.designpattern.builder.drink.Drink;
import com.designpattern.builder.hamburger.Hamburger;
import java.util.ArrayList;
import java.util.List;
public class MealShop {
private Hamburger hamburger;
private Drink drink;
private List<Food> foods;
private Customer customer;
public MealShop() {
}
public MealShop acceptCustomer(Customer customer, Hamburger hamburger, Drink drink) {
this.customer = customer;
this.hamburger = hamburger;
this.drink = drink;
this.foods = new ArrayList<>();
return this;
}
public MealShop addFood(Food food) {
if (!this.foods.contains(food))
this.foods.add(food);
return this;
}
public void broadcast() {
System.out.println(this.toString());
}
@Override
public String toString() {
StringBuffer sb = new StringBuffer(customer.getName())
.append(" : ")
.append(hamburger.toString())
.append(drink.toString());
for (Food food:foods) {
sb.append(food.toString());
}
return sb.toString();
}
}
开始消费
package com.designpattern.builder;
import com.designpattern.builder.dessert.Dessert;
import com.designpattern.builder.dessert.IceCream;
import com.designpattern.builder.dessert.Pudding;
import com.designpattern.builder.dessert.Sundae;
import com.designpattern.builder.drink.CocaCola;
import com.designpattern.builder.drink.Drink;
import com.designpattern.builder.drink.PepsiCola;
import com.designpattern.builder.drink.Wahaha;
import com.designpattern.builder.hamburger.BeefHamburger;
import com.designpattern.builder.hamburger.ChickenHamburger;
import com.designpattern.builder.hamburger.Hamburger;
import com.designpattern.builder.hamburger.PorkHamburger;
import com.designpattern.builder.salad.FruitSalad;
import com.designpattern.builder.salad.Salad;
import com.designpattern.builder.salad.VegetableSalad;
import com.designpattern.builder.snack.ChickenNuggets;
import com.designpattern.builder.snack.FrenchFries;
import com.designpattern.builder.snack.Snack;
public class Application {
public static void main(String[] args) {
//开店
MealShop shop = new MealShop();
//准备食物
//Hamburger
Hamburger beefHamburger = new BeefHamburger();
Hamburger porkHamburger = new PorkHamburger();
Hamburger chickenHamburger = new ChickenHamburger();
//Drink
Drink cocaCola = new CocaCola();
Drink pepsiCola = new PepsiCola();
Drink wahaha = new Wahaha();
//Dessert
Dessert sundae = new Sundae();
Dessert iceCream = new IceCream();
Dessert pudding = new Pudding();
//Salad
Salad vegetableSalad = new VegetableSalad();
Salad fruitSalad = new FruitSalad();
//Snack
Snack frenchFries = new FrenchFries();
Snack chickenNuggets = new ChickenNuggets();
//第一个顾客
Customer customerA = new Customer("A");
//点单
shop.acceptCustomer(customerA, beefHamburger, pepsiCola)
.addFood(vegetableSalad);
shop.broadcast();
//第二个顾客
Customer customerB = new Customer("B");
shop.acceptCustomer(customerB, chickenHamburger, wahaha)
.addFood(fruitSalad)
.addFood(chickenNuggets)
.addFood(pudding);
shop.broadcast();
}
}
输出:
A : Hamburger = BeefHamburger;Drink = Pepsi Cola;Salad = Vegetable salad;
B : Hamburger = ChickenHamburger;Drink = Wahaha;Salad = Fruit Salad;Snack = Chicken Nuggets;Dessert = Pudding;
总结
使用该模式的关键有两点:
- 添加的对象一定需要一个统一的接口或者父类
- 方法的返回值是该方法所属的对象本身。