zoukankan      html  css  js  c++  java
  • 设计模式(3)——建造者模式的初步学习与案例演示

    建造者模式

    建造者模式(Builder Pattern)使用多个简单的对象一步一步构建成一个复杂的对象。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。

    一个 Builder 类会一步一步构造最终的对象。该 Builder 类是独立于其他对象的。

    介绍

    意图:将一个复杂的构建与其表示相分离,使得同样的构建过程可以创建不同的表示。

    主要解决:主要解决在软件系统中,有时候面临着"一个复杂对象"的创建工作,其通常由各个部分的子对象用一定的算法构成;由于需求的变化,这个复杂对象的各个部分经常面临着剧烈的变化,但是将它们组合在一起的算法却相对稳定。

    何时使用:一些基本部件不会变,而其组合经常变化的时候。

    如何解决:将变与不变分离开。

    关键代码:建造者:创建和提供实例,导演:管理建造出来的实例的依赖关系。

    应用实例: 1、去肯德基,汉堡、可乐、薯条、炸鸡翅等是不变的,而其组合是经常变化的,生成出所谓的"套餐"。 2、JAVA 中的 StringBuilder。

    优点: 1、建造者独立,易扩展。 2、便于控制细节风险。

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

    使用场景: 1、需要生成的对象具有复杂的内部结构。 2、需要生成的对象内部属性本身相互依赖。

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

    实现

    我们假设一个快餐店的商业案例,其中,一个典型的套餐可以是一个汉堡(Burger)和一杯冷饮(Cold drink)。汉堡(Burger)可以是素食汉堡(Veg Burger)或鸡肉汉堡(Chicken Burger),它们是包在纸盒中。冷饮(Cold drink)可以是可口可乐(coke)或百事可乐(pepsi),它们是装在瓶子中。

    我们将创建一个表示食物条目(比如汉堡和冷饮)的 Item 接口和实现 Item 接口的实体类,以及一个表示食物包装的 Packing 接口和实现 Packing 接口的实体类,汉堡是包在纸盒中,冷饮是装在瓶子中。

    然后我们创建一个 Meal 类,带有 Item 的 ArrayList 和一个通过结合 Item 来创建不同类型的 Meal 对象的 MealBuilderBuilderPatternDemo,我们的演示类使用 MealBuilder 来创建一个 Meal

    建造者模式的 UML 图

    代码实现步骤:

    一、创建一个表示食物条目和食物包装的接口。

    1 /**
    2  * 条目类
    3  */
    4 public interface Item {
    5     String name();//名称
    6     Packing packing();//包装
    7     float price();//价格
    8 }
    1 /**
    2  * 包装类
    3  */
    4 public interface Packing {
    5     String pack();
    6 }

    二、创建实现 Packing 接口的实体类。

    1 /**
    2  * 瓶子类
    3  */
    4 public class Bottle implements Packing {
    5     @Override
    6     public String pack() {
    7         return "瓶子(Bottle)";
    8     }
    9 }
    1 /**
    2  * 纸盒类
    3  */
    4 public class Wrapper implements Packing {
    5     @Override
    6     public String pack() {
    7         return "纸盒(Wrapper)";
    8     }
    9 }

    三、创建实现 Item 接口的抽象类,该类提供了默认的功能。

    /**
     * 汉堡类
     */
    public abstract class Burger implements Item {
        @Override
        public Packing packing() {
            //汉堡都是使用盒装
            return new Wrapper();
        }
    
        @Override
        public abstract float price();
    }
    

      

    /**
     * 饮品类
     */
    public abstract class ColdDrink implements Item {
        @Override
        public Packing packing() {
            //饮品都是使用瓶子
            return new Bottle();
        }
    
        @Override
        public abstract float price();
    }
    

    四、创建扩展了 Burger 和 ColdDrink 的实体类。

    /**
     * 鸡肉汉堡
     */
    public class ChickenBurger extends Burger {
        @Override
        public String name() {
            return "鸡肉汉堡(ChickenBurger )";
        }
    
        @Override
        public float price() {
            return 50.5f;
        }
    }
    

      

    /**
     * 素食汉堡
     */
    public class VegBurger extends Burger {
        @Override
        public String name() {
            return "VegBurger(素食汉堡) ";
        }
    
        @Override
        public float price() {
            return 12.9f;
        }
    }
    

      

    /**
     * 可口可乐
     */
    public class Coke extends ColdDrink {
        @Override
        public String name() {
            return "可口可乐(Coke)";
        }
    
        @Override
        public float price() {
            return 7;
        }
    }
    

      

    /**
     * 百事可乐
     */
    public class Pepsi extends ColdDrink {
        @Override
        public String name() {
            return "百事可乐(Pepsi)";
        }
    
        @Override
        public float price() {
            return 5;
        }
    }
    

    五、创建一个 Meal 类,带有上面定义的 Item 对象。

    import java.util.ArrayList;
    import java.util.List;
    
    /**
     * 菜单类
     */
    public class Meal {
        private List<Item> itemList = new ArrayList<>();
        //往条目里添加信息
        public void addItem(Item item){
            itemList.add(item);
        }
        //计算价格和
        public float getCost(){
            float cost = 0.0f;
            for(Item item:itemList){
                cost+=item.price();
            }
            return cost;
        }
        //展示条目
        public void showItems(){
            for(Item item:itemList){
                System.out.print("名称:"+item.name()+"	");
                System.out.print("包装:"+item.packing().pack()+"	");
                System.out.println("价格:"+item.price());
            }
        }
    
    }
    

    六、创建一个 MealBuilder 类,实际的 builder 类负责创建 Meal 对象。

    /**
     * 菜单建造者类
     */
    public class MealBuilder {
        //套餐一:素食汉堡+可口可乐
        public Meal mealOne(){
            Meal meal = new Meal();
            meal.addItem(new VegBurger());
            meal.addItem(new Coke());
            return meal;
        }
        //套餐二:鸡肉汉堡+百事可乐
        public Meal mealTwo(){
            Meal meal = new Meal();
            meal.addItem(new ChickenBurger());
            meal.addItem(new Pepsi());
            return meal;
        }
        //套餐三:素食汉堡+百世可乐
        public Meal mealThree(){
            Meal meal = new Meal();
            meal.addItem(new VegBurger());
            meal.addItem(new Pepsi());
            return meal;
        }
        //套餐四:鸡肉汉堡+可口可乐
        public Meal mealFour(){
            Meal meal = new Meal();
            meal.addItem(new ChickenBurger());
            meal.addItem(new Coke());
            return meal;
        }
    }
    

    七、BuiderTest 使用 MealBuider 来演示建造者模式(Builder Pattern)。

    /**
     * 建造者模式测试类
     */
    public class BuilderTest {
        public static void main(String[] args) {
            MealBuilder mealBuilder = new MealBuilder();
            Meal mealOne = mealBuilder.mealOne();
            System.out.println("套餐一:");
            mealOne.showItems();
            System.out.println("价格总计:"+mealOne.getCost());
            System.out.println("--------------------------------");
    
            Meal mealTwo = mealBuilder.mealTwo();
            System.out.println("套餐二:");
            mealTwo.showItems();
            System.out.println("价格总计:"+mealTwo.getCost());
            System.out.println("--------------------------------");
    
    
            Meal mealThree = mealBuilder.mealThree();
            System.out.println("套餐三:");
            mealThree.showItems();
            System.out.println("价格总计:"+mealThree.getCost());
            System.out.println("--------------------------------");
    
            Meal mealFour = mealBuilder.mealFour();
            System.out.println("套餐四:");
            mealFour.showItems();
            System.out.println("价格总计:"+mealFour.getCost());
            System.out.println("--------------------------------");
        }
    }
    

    八、输出结果。

    套餐一:
    名称:VegBurger(素食汉堡)     包装:纸盒(Wrapper)    价格:12.9
    名称:可口可乐(Coke)    包装:瓶子(Bottle)    价格:7.0
    价格总计:19.9
    --------------------------------
    套餐二:
    名称:鸡肉汉堡(ChickenBurger )    包装:纸盒(Wrapper)    价格:50.5
    名称:百事可乐(Pepsi)    包装:瓶子(Bottle)    价格:5.0
    价格总计:55.5
    --------------------------------
    套餐三:
    名称:VegBurger(素食汉堡)     包装:纸盒(Wrapper)    价格:12.9
    名称:百事可乐(Pepsi)    包装:瓶子(Bottle)    价格:5.0
    价格总计:17.9
    --------------------------------
    套餐四:
    名称:鸡肉汉堡(ChickenBurger )    包装:纸盒(Wrapper)    价格:50.5
    名称:可口可乐(Coke)    包装:瓶子(Bottle)    价格:7.0
    价格总计:57.5
    --------------------------------

    参考资料来源于菜鸟教程https://www.runoob.com/design-pattern/builder-pattern.html

  • 相关阅读:
    元素模式
    完美C++(第5版)(双色)
    ASP.NET Web API 2框架揭秘
    跨终端 Web
    WebKit技术内幕
    云计算时代——本质、技术、创新、战略
    互联网创业密码
    Netty权威指南
    Robot Framework 学习笔记(二)-------第一个脚本
    Robot Framework学习笔记(一)------环境搭建
  • 原文地址:https://www.cnblogs.com/zaevn00001/p/12617742.html
Copyright © 2011-2022 走看看