建造者模式定义
建造者模式 使用多个简单的对象一步一步构建成一个复杂的对象。建造者模式属于创建型模式
目的
将复杂的构建和表示分离,主要使用在一些基本的部件不改变,但是其组合会经常的发生改变。
优点
- 分离构建过程和表示,构建更加灵活,可以构建不同的表示
- 更好的控制构建过程,隐藏构建细节
- 代码复用高,不同的构建中使用相同的建造者
缺点
- 产品属性少,代码冗余
- 构建增加了类和对象的数量
使用场景
1、需要生成的对象具有复杂的内部结构。
2、需要生成的对象内部属性本身相互依赖。
与工厂模式的区别是:建造者模式更加关注与零件装配的顺序。
实例
餐饮
餐饮背景下的套餐搭配,套餐包含了蔬菜鸡肉汉堡搭配可乐果汁饮品的套餐组合。 BuildClient 是消费者,MealBuilder 是创建好的套餐配置,包含了套餐的详情和套餐费用。PrepareMealBuilder 是后台准备套餐。Item 是打包产品,包含了汉堡和饮品。Burger 是鸡肉汉堡和蔬菜汉堡,Drink 是果汁饮品和可口饮品。Packing 是打包接口,实现了瓶装和纸质包装接口实现。
代码
包装接口和实现类
public interface Packing {
String packing();
}
public class Bottle implements Packing{
@Override
public String packing() {
return "Bottle 瓶包装";
}
}
public class Wrapper implements Packing{
@Override
public String packing() {
return "Wrapper 纸包装";
}
}
产品接口设计
public interface Item {
String name();
String packing();
Float calPrice();
}
汉堡和饮品类
public abstract class Burger implements Item{
@Override
public String packing() {
return new Wrapper().packing();
}
}
public class ChickenBurger extends Burger{
@Override
public String name() {
return "ChickenBurger 鸡肉汉堡";
}
@Override
public Float calPrice() {
return 15.0F;
}
}
public class VegBurger extends Burger{
@Override
public String name() {
return "VegBurger 蔬菜汉堡";
}
@Override
public Float calPrice() {
return 10.0F;
}
}
public abstract class Drink implements Item{
@Override
public String packing() {
return new Bottle().packing();
}
}
public class CockDrink extends Drink{
@Override
public String name() {
return "CockDrink 可口可乐饮品";
}
@Override
public Float calPrice() {
return 3.0F;
}
}
public class JuiceDrink extends Drink{
@Override
public String name() {
return "JuiceDrink 果汁饮品";
}
@Override
public Float calPrice() {
return 5.0F;
}
}
预先准备套餐
public class PrepareMealBuilder {
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.calPrice();
}
return cost;
}
public void printItems(){
for (Item item : items){
System.out.println(item.name()+"采用了"+item.packing()+"打包,花费了"+item.calPrice()+"¥");
}
System.out.println();
}
}
组合的套餐项目
public class MealBuilder {
public void makeVegCockMeal(){
PrepareMealBuilder pmb = new PrepareMealBuilder();
pmb.addItem(new VegBurger());
pmb.addItem(new CockDrink());
System.out.println("makeVegCockMeal 产品总共消费了"+pmb.getCost() + "¥");
pmb.printItems();
}
public void makeVegJuiceMeal(){
PrepareMealBuilder pmb = new PrepareMealBuilder();
pmb.addItem(new VegBurger());
pmb.addItem(new JuiceDrink());
System.out.println("makeVegJuiceMeal 产品总共消费了"+pmb.getCost() + "¥");
pmb.printItems();
}
public void makeChickenCockMeal(){
PrepareMealBuilder pmb = new PrepareMealBuilder();
pmb.addItem(new ChickenBurger());
pmb.addItem(new CockDrink());
System.out.println("makeChickenCockMeal 产品总共消费了"+pmb.getCost() + "¥");
pmb.printItems();
}
public void makeChickenJuiceMeal(){
PrepareMealBuilder pmb = new PrepareMealBuilder();
pmb.addItem(new ChickenBurger());
pmb.addItem(new JuiceDrink());
System.out.println("makeChickenJuiceMeal 产品总共消费了"+pmb.getCost() + "¥");
pmb.printItems();
}
}
消费者使用
public class BuildClient {
public static void main(String[] args) {
MealBuilder mealBuilder = new MealBuilder();
mealBuilder.makeChickenCockMeal();
mealBuilder.makeVegJuiceMeal();
}
}
电脑构建
电脑具有品牌,内存,CPU型号属性。抽象的电脑构建,通过方法区在子类中具体实现构建戴尔和联想的电脑产品。ComputerBuilder 只有一个构建抽象电脑的方法。构建后统一由客户端调用。
代码
电脑类
@Data
public class Computer {
private String brand;
private Integer memory;
private String cpu;
}
抽象电脑构建器
public abstract class AbstractComputerBuilder {
protected Computer computer = new Computer();
public abstract void buildBrand();
public abstract void buildMemory();
public abstract void buildCpu();
public Computer buildComputer(){
return computer;
}
}
具体的电脑配置
public class LenovoComputerBuilder extends AbstractComputerBuilder{
@Override
public void buildBrand() {
computer.setBrand("Lenovo");
}
@Override
public void buildMemory() {
computer.setMemory(16);
}
@Override
public void buildCpu() {
computer.setCpu("i7");
}
}
public class DellComputerBuilder extends AbstractComputerBuilder {
@Override
public void buildBrand() {
computer.setBrand("Dell");
}
@Override
public void buildMemory() {
computer.setMemory(8);
}
@Override
public void buildCpu() {
computer.setCpu("i5");
}
}
电脑构建器,提供给用户
public class ComputerBuilder {
private Computer computer;
/**
逐步构建复杂的对象
*/
public Computer build(AbstractComputerBuilder abstractComputerBuilder){
if (computer == null){
computer = new Computer();
}
abstractComputerBuilder.buildBrand();
abstractComputerBuilder.buildMemory();
abstractComputerBuilder.buildCpu();
computer = abstractComputerBuilder.buildComputer();
return computer;
}
}
在BuildClient 的 main 方法中
public class BuildClient {
public static void main(String[] args) {
ComputerBuilder computerBuilder = new ComputerBuilder();
Computer dell = computerBuilder.build(new DellComputerBuilder());
System.out.println(dell.toString());
System.out.println(computerBuilder.build(new LenovoComputerBuilder()).toString());
}
}
构建 Person
人是男人和女人,具有头,身体,脚属性。人构建器接口具体实现男人构建器和女人构建器。在PersonDirector 中统一构建提供给用户使用。
代码
@Data
public class Person {
String head;
String body;
String foot;
}
class Man extends Person{
}
class Women extends Person{
}
构建器构建
public interface PersonBuilder {
void buildHead();
void buildBody();
void buildFoot();
Person buildPerson();
}
public class ManBuilder implements PersonBuilder{
private Person person = new Man();
@Override
public void buildHead() {
person.setHead("构建 Man 头");
}
@Override
public void buildBody() {
person.setBody("构建 Man 身体");
}
@Override
public void buildFoot() {
person.setFoot("构建 Man 脚");
}
@Override
public Person buildPerson() {
return person;
}
}
public class WomenBuilder implements PersonBuilder{
private Person person = new Women();
@Override
public void buildHead() {
person.setHead("构建 Women 头");
}
@Override
public void buildBody() {
person.setBody("构建 Women 身体");
}
@Override
public void buildFoot() {
person.setFoot("构建 Women 脚");
}
@Override
public Person buildPerson() {
return person;
}
}
统一构建器提供给用户
public class PersonDirector {
public Person buildPersonBuilder(PersonBuilder personBuilder){
personBuilder.buildHead();
personBuilder.buildBody();
personBuilder.buildFoot();
return personBuilder.buildPerson();
}
}
用户使用
public class BuildClient {
public static void main(String[] args) {
Person man = new PersonDirector().buildPersonBuilder(new ManBuilder());
System.out.println(man.getHead() + man.getBody() + man.getFoot());
Person women = new PersonDirector().buildPersonBuilder(new WomenBuilder());
System.out.println(women.getHead() + women.getBody() + women.getFoot());
}
}