建造者模式

1、建造者模式的概念

建造者模式,英文Builder Pattern,属于创建型模式,该模式组合多个简单的对象来构造一个复杂的对象。会有一个Builder类,而该类负责构造最终的复杂对象。

2、建造者模式的特点

  • 组合多个简单对象,构造复杂对象。
  • 由构造类Builder来构造最终的对象。

3、关于建造者模式

  • 使用目的:将一个复杂的构建与其表示分离,使得同样的构建能产生不同的组合。
  • 解决问题:在开发时,有时候需要创建一个复杂的对象,而这个对象是由多个简单的子对象组合而成的。有时候需要有一点变化,所以希望组合方式不同,但是组合的过程却是一样的。
  • 使用时机:基本组件不变,而组合方式经常发生变化。
  • 保证建造者:将变化的部分和不变化的部分分离。
  • 建造者关键:由一个Builder类来创建提供实例,另一个类负责管理该实例的依赖。

4、建造者模式的优缺点

优点

  • 建造者独立,易扩展。
  • 便于控制细节风险。

缺点

  • 产品必须有共同点,范围有限制。
  • 如果内部变化复杂,那么需要很多的建造类Builder类。

5、建造者模式的使用场景

  • 需要生成的对象具有复杂的内部结构。
  • 需要生成的对象内部属性本身相互依赖。

需要注意建造者模式和工厂模式的区别。

6、建造者模式的实现

我们在去KFC吃东西的时候,假如点的套餐是汉堡 + 饮料,那么汉堡可以是牛肉汉堡,也可以是鸡肉汉堡等,店家是使用纸盒来包装汉堡的,饮料可以是可乐,也可以是苹果汁,橙汁等,店家是使用瓶子来装饮料的。所以这里可以创建一个食物条目的Item接口和实现类,然后创建包装Pack的接口和实现类,然后创建一个Food类,该类中带有食物条目Item对象,然后再创建一个FoodBuilder类来产生不同的Food类对象(组合不同的汉堡和饮料)。

(1)创建Pack接口和实现类

/*
 * 这个接口表示包装,纸盒还是瓶子
 */
public interface Pack {
    
    // 获取包装名称
    public String getPackName();

}

// 纸盒包装
public class PaperBox implements Pack{

    @Override
    public String getPackName() {
        return "使用纸盒包装汉堡!";
    }

}
// 瓶子包装
public class Bottle implements Pack{

    @Override
    public String getPackName() {
        return "饮料进行装瓶!";
    }

}

(2)创建Item接口和抽象实现类

/*
 * 该接口表示食物的条目
 */
public interface Item {
    
    // 获取食物名称
    public String getFoodName();
    
    // 获取包装
    public Pack packing();
    
    // 获取价格
    public float getPrice();

创建Hamburger抽象类,表示汉堡,实现Item接口。

/*
 * 汉堡抽象类,实现接口,可以不实现接口中的方法
 * 也可以重写接口中的方法
 */
public abstract class Hamburger implements Item{

    // 汉堡使用纸盒打包
    @Override
    public Pack packing() {
        return new PaperBox();
    }

    // 这个方法不实现
    @Override
    public abstract float getPrice();
   
}

创建Hamburger抽象类的子类:

// 鸡肉汉堡
public class ChickenHamburger extends Hamburger{

    @Override
    public String getFoodName() {
        return "美味的鸡肉汉堡!";
    }

    @Override
    public float getPrice() {
        return 7.5f;
    }

}
// 牛肉汉堡
public class BeefHamburger extends Hamburger{

    @Override
    public String getFoodName() {
        return "美味的牛肉汉堡!";
    }

    @Override
    public float getPrice() {
        return 8.5f;
    }
    
}

创建Drink抽象类,表示饮料,实现Item接口。

/*
 * 饮料抽象类
 */
public abstract class Drink implements Item{

    // 饮料使用瓶子进行打包
    @Override
    public Pack packing() {
        return new Bottle();
    }

    // 这个方法不实现
    @Override
    public abstract float getPrice();
    
}

创建Drink抽象类的子类:

/*
 * 饮料的子类,可乐
 */
public class Coke extends Drink{

    @Override
    public String getFoodName() {
        return "可口可乐,畅饮无限!";
    }

    @Override
    public float getPrice() {
        return 4.5f;
    }

}
/*
 * 饮料子类,橙汁
 */
public class OrangeJuice extends Drink{

    @Override
    public String getFoodName() {
        return "鲜榨橙汁!";
    }

    @Override
    public float getPrice() {
        return 3.0f;
    }

}

(3)创建Food类

创建Food类,会带有Item接口。

public class Food {

    // 食物条目列表
    private List<Item> items = new ArrayList<>();

    // 添加食物条目
    public void addItems(Item item) {
        items.add(item);
    }

    // 计算总价格
    public float getTotalPrice() {
        float total = 0.0f;
        for (Item item : items) {
            total += item.getPrice();
        }
        return total;
    }
    
    // 输出信息
    public void showItems() {
        for(Item item:items) {
            System.out.println("名称:" + item.getFoodName() 
                   + ",打包:" + item.packing().getPackName()
                   + ",价格:" + item.getPrice());
        }
    }

}

(4)创建FoodBuilder类

创建一个FoodBuilder类,该类负责构建Food类对象,Food类对象是最终要构建的对象,使用了多个简单子对象进行构建。

/*
 * 该Builder类只负责构建Food类对象
 * 使用多个简单对象进行组合
 */
public class FoodBuilder {
    
    // 鸡肉汉堡 + 可乐套餐
    public Food chickenBurgeAndCoke() {
        Food food = new Food();
        food.addItem(new ChickenHamburger());
        food.addItem(new Coke());
        return food;
    }
    
    // 牛肉汉堡 + 可乐套餐
    public Food beefBurgeAndCoke() {
        Food food = new Food();
        food.addItem(new BeefHamburger());
        food.addItem(new Coke());
        return food;
    }
    
    // 鸡肉汉堡 + 橙汁套餐
    public Food chickenBurgeAndOrangeJuice() {
        Food food = new Food();
        food.addItem(new ChickenHamburger());
        food.addItem(new OrangeJuice());
        return food;
    }
    
    // 牛肉汉堡 + 橙汁套餐
    public Food beefBurgeAndOrangeJuice() {
        Food food = new Food();
        food.addItem(new BeefHamburger());
        food.addItem(new OrangeJuice());
        return food;
    }

}

(5)测试

public class Test {

    public static void main(String[] args) {
        // FoodBuilder对象
        FoodBuilder foodBuilder = new FoodBuilder();
        // 套餐一组合
        Food chickenCoke = foodBuilder.chickenBurgeAndCoke();
        chickenCoke.showItems();
        System.out.println("总计:" + chickenCoke.getTotalPrice() + "元");
        System.out.println("-----------------------------------------");
        // 套餐二组合
        Food beefCoke = foodBuilder.beefBurgeAndCoke();
        beefCoke.showItems();
        System.out.println("总计:" + beefCoke.getTotalPrice() + "元");
        System.out.println("-----------------------------------------");
        // 套餐三组合
        Food chickenJucie = foodBuilder.chickenBurgeAndOrangeJuice();
        chickenJucie.showItems();
        System.out.println("总计:" + chickenJucie.getTotalPrice() + "元");
        System.out.println("-----------------------------------------");
        // 套餐四组合
        Food beefJucie = foodBuilder.beefBurgeAndOrangeJuice();
        beefJucie.showItems();
        System.out.println("总计:" + beefJucie.getTotalPrice() + "元");
    }

}

在这里插入图片描述
7、小结

建造者模式属于创建型模式,其特点是组合多个简单的子对象,来构建一个最终的复杂对象,涉及到一个Builder类来构建最终对象。如果希望有多种组合方式,但是组合过程不变的话,那么使用该模式会是很好的解决方法。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值