• 设计模式(五):建造者模式


    1. 建造者模式的介绍

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

    优点:

    1. 分离构建过程和表示,使得构建过程更加灵活,可以构建不同的表示。
    2. 可以更好地控制构建过程,隐藏具体构建细节。
    3. 代码复用性高,可以在不同的构建过程中重复使用相同的建造者。

    缺点:

    1. 如果产品的属性较少,建造者模式可能会导致代码冗余。
    2. 建造者模式增加了系统的类和对象数量。

    2. 建造者模式的类图

    一个中式快餐店,推出两种早餐套餐:

    • 套餐一:一次性碗装甜豆浆 + 热干面
    • 套餐二:一次性碗装咸豆浆 + 炸酱面

    针对上述场景,将创建一个食物的接口Food和实现Food接口的具体食物类,以及食物包装接口Pack和实现Pack接口的具体包装类。然后创建Meal套餐类,包含一个装FoodList,最后创建一个 MealBuilder类,用来生成不同的Meal套餐。

    在这里插入图片描述

    3. 建造者模式的实现

    3.1 创建食物接口

    package blog;
    
    /**
     * 食物
     */
    public interface Food {
        String getName();
    
        String getDescription();
    
        String getPrice();
    
        Pack getPack();
        
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    package blog;
    
    /**
     * 豆浆
     */
    public abstract class Soymilk implements Food {
    
        @Override
        public Pack getPack() {
            return new DisposablePack();
        }
    
        abstract String getTaste();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    package blog;
    
    /**
     * 面条
     */
    public abstract class Noodles implements Food {
        abstract String getType();
    
        @Override
        public Pack getPack() {
            return new NormalPack();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    3.2 创建包装接口

    package blog;
    
    /**
     * 包装
     */
    public interface Pack {
        String getName();
    
        String getType();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    3.3 创建具体包装

    package blog;
    
    /**
     * 一次性包装
     */
    public class DisposablePack implements Pack{
        @Override
        public String getName() {
            return "一次性包装";
        }
    
        @Override
        public String getType() {
            return "一次性";
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    package blog;
    
    /**
     * 普通包装
     */
    public class NormalPack implements Pack{
        @Override
        public String getName() {
            return "普通包装";
        }
    
        @Override
        public String getType() {
            return "普通";
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    3.4 创建具体食物

    package blog;
    
    /**
     * 甜豆浆
     */
    public class SweetSoymilk extends Soymilk {
    
        @Override
        public String getName() {
            return "甜豆浆";
        }
    
        @Override
        public String getDescription() {
            return "甜味的豆浆";
        }
    
        @Override
        public String getPrice() {
            return "2元";
        }
    
        @Override
        public String getTaste() {
            return "甜";
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    package blog;
    
    /**
     * 咸豆浆
     */
    public class SalineSoymilk extends Soymilk {
    
        @Override
        public String getName() {
            return "咸豆浆";
        }
    
        @Override
        public String getDescription() {
            return "咸味的豆浆";
        }
    
        @Override
        public String getPrice() {
            return "1.5元";
        }
    
        @Override
        public String getTaste() {
            return "咸";
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    package blog;
    
    /**
     * 热干面
     */
    public class HotDryNoodles extends Noodles {
    
        @Override
        public String getName() {
            return "武汉热干面";
        }
    
        @Override
        public String getDescription() {
            return "武汉的热干面";
        }
    
        @Override
        public String getPrice() {
            return "5元";
        }
    
        @Override
        public String getType() {
            return "武汉版";
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    package blog;
    
    /**
     * 炸酱面
     */
    public class SauceNoodles extends Noodles {
    
        @Override
        public String getName() {
            return "炸酱面";
        }
    
        @Override
        public String getDescription() {
            return "北京炸酱面";
        }
    
        @Override
        public String getPrice() {
            return "10元";
        }
    
        @Override
        public String getType() {
            return "北京版";
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    3.5 创建Meal类

    package blog;
    
    import java.util.ArrayList;
    import java.util.List;
    
    /**
     * 套餐
     */
    public class Meal {
        private List<Food> meal = new ArrayList<>();
    
        public void addFood(Food food) {
            meal.add(food);
        }
    
        public void showMeal() {
            meal.forEach(food -> {
                System.out.print(food.getPack().getName() + food.getName() + food.getPrice() + " ");
            });
            System.out.println();
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    3.6 创建MealBuilder类

    package blog;
    
    /**
     * 构建套餐
     */
    public class MealBuilder {
        public Meal buildMeal1() {
            Meal meal = new Meal();
            meal.addFood(new SweetSoymilk());
            meal.addFood(new HotDryNoodles());
    
            return meal;
        }
    
        public Meal buildMeal2() {
            Meal meal = new Meal();
            meal.addFood(new SalineSoymilk());
            meal.addFood(new SauceNoodles());
            return meal;
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    3.7 演示建造者模式

    package blog;
    
    public class BuilderDemo {
        public static void main(String[] args) {
            MealBuilder mealBuilder = new MealBuilder();
    
            Meal meal1 = mealBuilder.buildMeal1();
            meal1.showMeal();
    
            Meal meal2 = mealBuilder.buildMeal2();
            meal2.showMeal();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
  • 相关阅读:
    springboot框架拦截器中HttpServletRequest 请求如何区分是图片上传流还是普通的字符流?
    浅谈-“指针”
    智能优化与机器学习结合算法实现数据分类matlab代码清单
    【u-boot】u-boot的驱动模型分析
    [MySQL][表的增删查改][二][Retrieve][SELECT][WHERE]详细讲解
    【STL】list的模拟实现
    麒麟V10系统打包Qt免安装包程序
    Linux·串口编程
    51单片机-定时计数器
    对Mysql中redo log、undo log、binlog深入理解
  • 原文地址:https://blog.csdn.net/wenqi1992/article/details/138143890