创建型模式之-建造者模式

创建型模式之-建造者模式

简介

​ 说到建造者模式,有些人可能比较陌生,那么StringBuilder.append().append()....=> StringBuilder应该不陌生吧,其实在Spark中也用到了类似的设计模式,SparkSession.builder.conf().appName().....getOrCreate() => SparkSession,类似于这样的模式,就是建造者模式

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

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

NOTE: Java中,抽象类implement interface的时候,不需重写interface中的抽象方法,当然也可以重写

Bottle  			--打包的具体实现类
Buger 				--抽象类
Coca 					--具体实现类
ColdDrinking  --抽象类,用来实现Item单品接口
Item 					--接口,代表一个单品
Meal				  --类,代表一个套餐,用来装载不同的Item
MealBuilder 	--建造者类,用来创建Meal套餐
NonVegBuger 	--素食汉堡,Buger的子类
Packing 			--打包方式接口
Pepsi 				--ColdDrink的具体实现类
TestCreatePatternDemo --程序入口
VegBuger 			--素食Buger,Buger的实现类
Wrapper 			--纸质的包装方式实现类

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

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

建造者模式将变与不变分离:

不变:创建者只能创建相应的对象

变:创建的对象的内部属性是复杂可变的

1 建造者模式图解

在这里插入图片描述

2 建造者模式的简单实现

2.1 目标对象的创建流程

//可以一次添加Item,不同的Item有不同的打包方式,不同的item有不同的价格,不同的item有不同的name
Meal meal = MealBuilder.build().addItem(new Item()).addItem(new Item)......
  
  meal.getCost()
  meal.showItems()
  meal.addItem() => this

2.2 建造者模式的具体代码

TestCreatePatternDemo
package com.shufang.create_type.builder_pattern;

// 测试的程序入口
public class TestCreatePatternDemo {
    public static void main(String[] args) {

        MealBuilder mealBuilder = new MealBuilder();

        //创建一个素食汉堡+可口可乐套餐
        Meal meal = mealBuilder.createVegMeal().addItem(new VegBuger()).addItem(new Coca());

        //创建一个肉食汉堡+百事可乐套餐
        Meal meal1 = mealBuilder.createNonVegMeal().addItem(new NonVegBuger()).addItem(new Pepsi());


        /** 输出结果如下:
         * 23.88
         * 单品名称:素食汉堡,单品价格:18.88,单品打包方式:wrapper packing(用包装纸打包)
         * 单品名称:可口可乐,单品价格:5.0,单品打包方式:bottle packing(用杯子打包)
         * ----------------
         * 25.8
         * 单品名称:非素食汉堡,单品价格:20.68,单品打包方式:wrapper packing(用包装纸打包)
         * 单品名称:百事可乐,单品价格:5.12,单品打包方式:bottle packing(用杯子打包)
         */
        System.out.println(meal.getCost());
        meal.getItemList();

        System.out.println("----------------");
        System.out.println(meal1.getCost());
        meal1.getItemList();

    }
}
MealBuilder
//建造者,用来创建简单的Meal对象
package com.shufang.create_type.builder_pattern;
/**
 * 建造者模式很常见:
 *      Java中的StringBuilder.append.append.append => StringBuilder
 *      Spark中的SparkSession.builder().conf().conf()
 *      .....
 * 这些都是建造者模式,在创建复杂对象的同时可以控制创建细节
 */
//用来创建不同的套餐组合
public class MealBuilder {

    // 创建一个素食套餐
    public Meal createVegMeal(){
        Meal meal = new Meal();

        return meal;
    };

    // 创建一个非素食套餐
    public Meal createNonVegMeal(){
        Meal meal = new Meal();
        return meal;
    };

}
Meal
//具体套餐类
package com.shufang.create_type.builder_pattern;

import java.util.ArrayList;

//这是一个事物套餐
public class Meal {
    //用来存储不同的套餐组成成员如:汉堡、可乐
    private ArrayList<Item> items = new ArrayList<Item>();

    //添加单品到套餐
    public Meal addItem(Item item) {
        items.add(item);
        System.out.println("item:" + item + " 添加成功");
        return this; //添加单品后,返回当前对象
    }

    //获取当前套餐的总消费
    public Double getCost() {
        Double cost = 0D;
        for (Item item : items) {
            cost += item.price();
        }
        return cost;
    }


    //获取明细单品
    public void getItemList(){
        for (Item item : items) {
            System.out.println("单品名称:"+item.name()+",单品价格:"+ item.price()+",单品打包方式:"+item.pack().pack());
        }
    }

}
Item
//单品的抽象接口
package com.shufang.create_type.builder_pattern;

//抽象单品,如Item「汉堡、打包方式、汉堡价格」
public interface Item {
    String name();

    Packing pack();

    Double price();
}
Buger
//汉堡,Item单品的具体实现
package com.shufang.create_type.builder_pattern;

//单品的具体实现之一、汉堡,这是一个抽象类,已经继承了接口的抽象方法,不需要实现
public abstract class Buger implements Item{

    //重写打包方法,只要是汉堡,都用包装纸打包,这是所有汉堡公共的,如果到子类实现的话,需要每个具体实例都要实现一遍该方法
    @Override
    public Packing pack() {
        return new Wrapper();
    }
}
ColdDrink
//冷饮,抽象类,具体实现自Item单品接口
package com.shufang.create_type.builder_pattern;

public abstract class ColdDrinking implements Item {


    //是要是冷饮,都用杯子bottle来进行打包
    @Override
    public Packing pack() {
        return new Bottle();
    }
}

Packing
//打包方式的接口抽象
package com.shufang.create_type.builder_pattern;

/**
 * 打包方式接口
 */
public interface Packing {
    String pack();
}

VegBuger
//具体是Buger汉堡的实现类,价格18.68
package com.shufang.create_type.builder_pattern;

public class VegBuger extends Buger {
    @Override
    public String name() {
        return "素食汉堡";
    }


    @Override
    public Double price() {
        return 18.88d;
    }
}
NonVegBuger
package com.shufang.create_type.builder_pattern;

//具体是汉堡Buger的实体类,名字叫非素食汉堡,价格20.68
public class NonVegBuger extends Buger {
    @Override
    public String name() {
        return "非素食汉堡";
    }


    @Override
    public Double price() {
        return 20.68d;
    }
}

Coca
//冷饮的具体实现类,可口可乐,价格5元
package com.shufang.create_type.builder_pattern;

public class Coca extends ColdDrinking {
    @Override
    public String name() {
        return "可口可乐";
    }



    @Override
    public Double price() {
        return 5.00d;
    }
}

Pepsi
//冷饮的具体实现类,百事可乐,价格5.12
package com.shufang.create_type.builder_pattern;

public class Pepsi extends ColdDrinking {
    @Override
    public String name() {
        return "百事可乐";
    }



    @Override
    public Double price() {
        return 5.12d;
    }
}

Wrapper
//打包方式的具体实现类,用纸盒打包
package com.shufang.create_type.builder_pattern;

// 具体的打包方式
public class Wrapper implements Packing {
    @Override
    public String pack() {
        return "wrapper packing(用包装纸打包)";
    }
}
Bottle
// 打包方式的具体实现类,用杯子打包
package com.shufang.create_type.builder_pattern;

public class Bottle implements Packing {

    @Override
    public String pack() {
        return "bottle packing(用杯子打包)";
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值