设计模式之建造者模式

建造者模式的定义

“Separate the construction of a complex object from its representation so that the same construction process can create different representations. ”
(将一个复杂的对象的构建与他的表示分离,使得相同的构建过程可以创建不同的表示。)

在建造者模式中,有如下3个角色:
Ⅰ.Product产品类
通常是实现了模板方法模式,也就是有模板方法和基本方法。下图中的Hamburg以及Drink的实现类就属于产品类。
Ⅱ.Builder建造者
返回一个组建好的数据。下图中的MealBuilder旧数据建造者。
Ⅲ.Director导演类
负责调用MealBuilder,告诉它需要怎么样的产品。比如说需要吃素餐,就调用prepareVegMeal方法,需要吃鸡肉餐,就调用prepareChickenMeal方法。

建造者模式


package com.example.demo.designpatterns;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

public class BuilderPatternDemo {
    public static void main(String[] args) {
        MealBuilder builder = new MealBuilder();
        Meal vegMeal = builder.prepareVegMeal();
        vegMeal.showItems();
        System.out.println("vegMeal cost money:" + vegMeal.getCost());

        Meal chickenMeal = builder.prepareChickenMeal();
        chickenMeal.showItems();
        System.out.println("chickenMeal cost money:" + chickenMeal.getCost());
    }
}

/**
 * 创建一个表示食物条目和食物包装的接口。
 */
interface Item{
    String name();
    Packing packing();
    BigDecimal price();
}

/**
 * 打包方式
 */
interface Packing{
    String pack();
}
/**
 * 打包盒
 */
class Wrapper implements Packing{
    @Override
    public String pack() {
        return "Wrapper";
    }
}
class Bottle implements Packing{
    @Override
    public String pack() {
        return "Bottle";
    }
}
abstract class Hamburg implements Item{
    @Override
    public Packing packing(){
        return new Wrapper();
    }
}
class VegHamburg extends Hamburg{
    @Override
    public String name() {
        return "蔬菜汉堡";
    }
    @Override
    public BigDecimal price() {
        return new BigDecimal(15);
    }
}
class ChickenHamburg extends Hamburg{
    @Override
    public String name() {
        return "鸡肉汉堡";
    }
    @Override
    public BigDecimal price() {
        return new BigDecimal(25);
    }
}
abstract class Drink implements Item{
    @Override
    public Packing packing(){
        return new Bottle();
    }
}
class ColdDrink extends Drink{
    @Override
    public String name() {
        return "冷饮";
    }
    @Override
    public BigDecimal price() {
        return new BigDecimal(10);
    }
}

class WarmDrink extends Drink{
    @Override
    public String name() {
        return "热饮";
    }
    @Override
    public BigDecimal price() {
        return new BigDecimal(15);
    }
}

class MealBuilder{
    public Meal prepareVegMeal(){
        Meal meal = new Meal();
        Item item = new VegHamburg();
        Item item1 = new WarmDrink();
        meal.addItem(item);
        meal.addItem(item1);
        return meal;
    }
    public Meal prepareChickenMeal(){
        Meal meal = new Meal();
        Item item = new ChickenHamburg();
        Item item1 = new ColdDrink();
        meal.addItem(item);
        meal.addItem(item1);
        return meal;
    }

}

class Meal{
    private List<Item> items = new ArrayList<Item>();

    public void addItem(Item item){
        items.add(item);
    }

    public BigDecimal getCost(){
        BigDecimal cost = BigDecimal.ZERO;
        for (Item item : items) {
            cost = cost.add(item.price());
        }
        return cost;
    }
    public void showItems(){
        for (Item item : items) {
            System.out.print("Item : "+item.name());
            System.out.print(", Packing : "+item.packing().pack());
            System.out.println(", price : "+item.price());
        }
    }
}

建造者模式的应用

  • 建造者模式的优点
    Ⅰ.封装性,使用建造者模式可以使客户不必知道产品内部组成的细节。
    Ⅱ.建造者独立,容易扩展。
    Ⅲ.便于控制细节风险。由于具体的建造者是独立的,因此可以对建造过程逐步细化,而不对其他的模块产生任何影响。

  • 建造者模式的使用场景
    Ⅰ.相同的方法,不同的执行顺序,产生不同的事件结果时,可以采用建造者模式。
    Ⅱ.多个部件和零件,都可以装配到一个对象中,但是产生的运行结果又不相同时,则可以使用该模式。
    Ⅲ.产品类非常复杂,或者产品类中的调用顺序不同产生了不同的效能,这个时候使用建造者模式非常合适。
    Ⅳ.在对象的创建过程中会使用到系统中的一些其他对象,这些对象在产品对象的创建过程中不易得到时,也可以采用建造者模式封装该对象的创建过程。

建造者模式的注意事项

建造者模式关注的是零件类型和装配工艺(顺序),这是它与工厂方法模式最大的不同的地方,虽然同为创建类模式,但是注重点不同。

建造者模式的最佳实践

在使用建造者模式的时候考虑一下模板方法模式,不要局限于思考一个模式,僵化的套用一个模式会让你受害无穷。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值