设计模式-创建型模式-建造者模式

51 阅读4分钟

建造者模式定义

建造者模式 BuilderPatternBuilder Pattern 使用多个简单的对象一步一步构建成一个复杂的对象。建造者模式属于创建型模式

目的

将复杂的构建和表示分离,主要使用在一些基本的部件不改变,但是其组合会经常的发生改变。

优点

  • 分离构建过程和表示,构建更加灵活,可以构建不同的表示
  • 更好的控制构建过程,隐藏构建细节
  • 代码复用高,不同的构建中使用相同的建造者

缺点

  • 产品属性少,代码冗余
  • 构建增加了类和对象的数量

使用场景

1、需要生成的对象具有复杂的内部结构。

2、需要生成的对象内部属性本身相互依赖。

与工厂模式的区别是:建造者模式更加关注与零件装配的顺序

实例

餐饮

餐饮背景下的套餐搭配,套餐包含了蔬菜鸡肉汉堡搭配可乐果汁饮品的套餐组合。 BuildClient 是消费者,MealBuilder 是创建好的套餐配置,包含了套餐的详情和套餐费用。PrepareMealBuilder 是后台准备套餐。Item 是打包产品,包含了汉堡和饮品。Burger 是鸡肉汉堡和蔬菜汉堡,Drink 是果汁饮品和可口饮品。Packing 是打包接口,实现了瓶装和纸质包装接口实现。

image.png

代码

包装接口和实现类

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 只有一个构建抽象电脑的方法。构建后统一由客户端调用。

image.png

代码

电脑类

@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 中统一构建提供给用户使用。

image.png

代码

@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());
    }
}