原创

【java设计模式】建造者模式

简单理解建造者模式

简单地说,就好象我要一座房子住,可是我不知道怎么盖(简单的砌墙,层次较低),也不知道怎么样设计(建几个房间,几个门好看,层次较高),于是我需要找一帮民工(Builder),他们会砌墙,还得找个设计师(Director),他知道怎么设计,我还要确保民工听设计师的领导,而设计师本身也不干活,光是下命令,这里砌一堵墙,这里砌一扇门,这样民工开始建设,最后,我可以向民工要房子了。在这个过程中,设计师是什么也没有干,除了他在脑子里的设计和命令,所以要房子也是跟民工要,记住了!

建造者模式(Builder Pattern)使用多个简单的对象一步一步构建成一个复杂的对象。它允许用户只通过指定复杂对象的类型和内容就可以构建它们,用户不需要知道内部的具体构建细节。

这个模式适用于:某个对象的构建过程复杂的情况下使用

建造者模式的优缺点

优点:

  • 分离了对象子组件的单独构造(由Builder来负责)和装配(由Director负责)。从而可以构造出复杂的对象。
  • 每一个具体建造者都相对独立,而与其他的具体建造者无关,因此可以很方便地替换具体建造者或增加新的具体建造者, 用户使用不同的具体建造者即可得到不同的产品对象
  • 实现了构建算法、装配算法的解耦,实现了更好的复用

缺点:

  • 产品必须有共同点,范围有限制。
  • 如内部变化复杂,会有很多的建造类。

模式结构

在这里插入图片描述

  • Product: 产品类所描述的是我们最终想要的到的结果统称
  • Builder: 建造者的接口定义,他定义了建造某种产品类需要的步骤,但不提供实现
  • ConcreteBuilder: 建造者的实现类,继承自 Builder 提供一种创建类型的具体步骤,是我们封装的拓展对象
  • Director: Builder 类的创建者,由他来为各种 Builder 来赋值属性,Director隔离了建造者实现类与实际客户端创建,让实际对象的创建只关注于对象的属性。

实例

建造者模式可以用于描述KFC如何创建套餐:套餐是一个复杂对象,它一般包含主食(如汉堡、鸡肉卷等)和饮料(如果汁、可乐等)等组成部分,不同的套餐有不同的组成部分,而KFC的服务员可以根据顾客的要求,一步一步装配这些组成部分,构造一份完整的套餐,然后返回给顾客。
在这里插入图片描述

实体类

主食和饮料

public class Food {
    private String name;

    public Food(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}
public class Drink {
    private String name;

    public Drink(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

Product

套餐

public class Meal {
    private Food food;
    private Drink drink;

    public Food getFood() {
        return food;
    }

    public void setFood(Food food) {
        this.food = food;
    }

    public Drink getDrink() {
        return drink;
    }

    public void setDrink(Drink drink) {
        this.drink = drink;
    }
}

Builder

抽象建造者

public abstract class MealBuilder {
    Meal meal = new Meal();
    public abstract void buildeFood();
    public abstract void buildeDrink();
    public Meal getMeal(){
        return meal;
    }
}

ConcreteBuilder

具体建造者:套餐A、套餐B

public class MealABuilder extends MealBuilder{
    @Override
    public void buildeFood() {
        meal.setFood(new Food("汉堡"));
    }

    @Override
    public void buildeDrink() {
        meal.setDrink(new Drink("可乐"));
    }
}
public class MealBBuilder extends MealBuilder{
    @Override
    public void buildeFood() {
        meal.setFood(new Food("鸡肉卷"));
    }

    @Override
    public void buildeDrink() {
        meal.setDrink(new Drink("芬达"));
    }
}

Director

服务员

public class Waiter {
    public void command(MealBuilder mealBuilder){
        mealBuilder.buildeFood();
        mealBuilder.buildeDrink();
    }
}

测试

public class Client {
    public static void main(String[] args) {
        MealBuilder mealBuilder = new MealABuilder();
        Waiter waiter = new Waiter();
        waiter.command(mealBuilder);
        Meal meal = mealBuilder.getMeal();
        System.out.println("套餐A:");
        System.out.println(meal.getFood().getName());
        System.out.println(meal.getDrink().getName());

        mealBuilder = new MealBBuilder();
        waiter.command(mealBuilder);
        waiter.command(mealBuilder);
        meal = mealBuilder.getMeal();
        System.out.println("套餐B:");
        System.out.println(meal.getFood().getName());
        System.out.println(meal.getDrink().getName());
    }
}

结果

套餐A:
汉堡
可乐
套餐B:
鸡肉卷
芬达
正文到此结束
本文目录