大话设计模式六:建造者模式

本文深入讲解了建造者模式,一种对象创建型模式,用于逐步构建复杂对象,将构建过程与表示分离,允许创建不同的产品对象。通过具体实例,如小饭店菜单组合,展示了如何使用建造者模式简化产品构建流程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一.模式定义

对象创建型模式。实现复杂对象的构建与表示分离,使得同样的构建过程可以创建不同的表示。
建造者模式是一步一步创建一个复杂的对象,它允许用户只通过指定复杂对象的类型和内容就可以构建它们,用户不需要知道内部的具体构建细节。
Builder Pattern: Separate the construction of a complex object from its representation so that the same construction process can create different representations. 

 

二.模式要素

建造者:负责以组装的形式生产出所需要的产品

零件:构成产品所需要的必要零件

产品:具体的产品,由零件灵活拼装而成

调用者

 

三.举例说明

在日常生活中我们一定有过去小饭店吃饭的经历,一些特色小店提供美味的主食和饮料,能够让人大快朵颐。

假设你开了一家小饭店,提供主食和饮料。其中主食有现烤面包、牛肉面,饮料有鲜榨橙汁、柠檬水。每来一位顾客都必须点单,不管其点了什么,点了多少,都能够组成一顿饭,关系图如下。现在作为饭店老板的你在想,当顾客点完一餐后,我需要根据顾客的点餐情况安排厨师去做,并且要知道这一餐的明细和总价,那怎么办呢?

很简单,建造者模式走起!

 

四.具体实例

工程结构如下:

 

1.IFood.java    主食接口

package builder;

/**
 * @program: DesignModes
 * @description: 主食接口
 * @author: Lei Dong
 * @create: 2018-10-04 10:38
 **/
public interface IFood {
    /**
     * 名称
     */
    String showName();

    /**
     * 价格
     */
    int showPrice();
}

 

2.Bread.java    现烤面包

package builder;

/**
 * @program: DesignModes
 * @description: 面包
 * @author: Lei Dong
 * @create: 2018-10-04 10:44
 **/
public class Bread implements IFood {
    private String name = "现烤面包";

    private int price = 6;

    @Override
    public String showName() {
        return this.name;
    }

    @Override
    public int showPrice() {
        return this.price;
    }
}

 

3.Noodles.java    牛肉面

package builder;

/**
 * @program: DesignModes
 * @description: 面条
 * @author: Lei Dong
 * @create: 2018-10-04 10:58
 **/
public class Noodles implements IFood {
    private String name = "牛肉面";

    private int price = 15;


    @Override
    public String showName() {
        return this.name;
    }

    @Override
    public int showPrice() {
        return this.price;
    }
}

 

4.IDrink.java    饮料接口

package builder;

/**
 * @program: DesignModes
 * @description: 饮料接口
 * @author: Lei Dong
 * @create: 2018-10-04 10:36
 **/
public interface IDrink {
    /**
     * 名称
     */
    String showName();

    /**
     * 价格
     */
    int showPrice();
}

 

5.OrangeJuice.java    鲜榨橙汁

package builder;

/**
 * @program: DesignModes
 * @description: 橙汁饮料
 * @author: Lei Dong
 * @create: 2018-10-04 10:39
 **/
public class OrangeJuice implements IDrink {
    private String name = "鲜榨橙汁";

    private int price = 10;

    @Override
    public String showName() {
        return this.name;
    }

    @Override
    public int showPrice() {
        return this.price;
    }
}

 

6.Lemonade.java    柠檬水

package builder;

/**
 * @program: DesignModes
 * @description: 柠檬水饮料
 * @author: Lei Dong
 * @create: 2018-10-04 10:42
 **/
public class Lemonade implements IDrink {
    private String name = "柠檬水";

    private int price = 2;

    @Override
    public String showName() {
        return this.name;
    }

    @Override
    public int showPrice() {
        return this.price;
    }
}

 

7.Meal.java    餐

package builder;

import java.util.List;

/**
 * @program: DesignModes
 * @description: 套餐
 * @author: Lei Dong
 * @create: 2018-10-04 10:47
 **/
class Meal {
    List<IFood> foodList;

    List<IDrink> drinkList;

    /**
     * 展示详情
     */
    void showDetail() {
        System.out.println("主食:");
        for(int i = 0; i < foodList.size(); i++) {
            System.out.println(foodList.get(i).showName());

        }

        System.out.println();

        System.out.println("饮料:");
        for(int i = 0; i < drinkList.size(); i++) {
            System.out.println(drinkList.get(i).showName());

        }
    }

    /**
     * 展示总价
     */
    void showTotalPrice() {
        int totalPrice = 0;
        for(int i = 0; i < foodList.size(); i++) {
            totalPrice += foodList.get(i).showPrice();
        }
        for(int i = 0; i < drinkList.size(); i++) {
            totalPrice += drinkList.get(i).showPrice();
        }
        System.out.println("总价:" + totalPrice + "元");
    }
}

 

8.MealBuilder.java    餐建造者

package builder;

import java.util.ArrayList;

/**
 * @program: DesignModes
 * @description: 套餐建造者
 * @author: Lei Dong
 * @create: 2018-10-04 10:47
 **/
class MealBuilder {
    private Meal meal;

    Meal obtainMeal() {
        return this.meal;
    }

    MealBuilder() {
        meal = new Meal();
        meal.drinkList = new ArrayList<>();
        meal.foodList = new ArrayList<>();
    }

    /**
     * 添加主食
     *
     * @param food
     */
    void addFood(IFood food) {
        if (food != null) {
            meal.foodList.add(food);
        }
    }

    /**
     * 添加饮料
     *
     * @param drink
     */
    void addDrink(IDrink drink) {
        if (drink != null) {
            meal.drinkList.add(drink);
        }
    }
}

 

9.Main.java    调用者

package builder;

/**
 * @program: DesignModes
 * @description: Main
 * @author: Lei Dong
 * @create: 2018-10-04 10:35
 **/
public class Main {
    public static void main(String[] args) {
        MealBuilder builder = new MealBuilder();
        builder.addDrink(new OrangeJuice());
        builder.addFood(new Noodles());
        builder.addFood(new Noodles());
        Meal meal = builder.obtainMeal();

        meal.showDetail();

        System.out.println();

        meal.showTotalPrice();
    }
}

 

运行结果;

 

五.总结

1.建造者模式优点
(1)客户端不必知道产品内部组成的细节,将产品本身与产品的创建过程解耦,使得相同的创建过程可以创建不同的产品对象。
(2)每一个具体建造者都相对独立,而与其他的具体建造者无关,因此可以很方便地替换具体建造者或增加新的具体建造者,用户使用不同的具体建造者即可得到不同的产品对象。
(3)可以更加精细地控制产品的创建过程。将复杂产品的创建步骤分解在不同的方法中,使得创建过程更加清晰,也更方便使用程序来控制创建过程。
(4)增加新的具体建造者无须修改原有类库的代码,指挥者类针对抽象建造者类编程,系统扩展方便,符合“开闭原则”。

2.建造者模式缺点
(1)建造者模式所创建的产品一般具有较多的共同点,其组成部分相似,如果产品之间的差异性很大,则不适合使用建造者模式,因此其使用范围受到一定的限制。
(2)如果产品的内部变化复杂,可能会导致需要定义很多具体建造者类来实现这种变化,导致系统变得很庞大。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值