简介
建造者模式(Builder Pattern),是使用多个简单的对象一步步构建成一个复杂的对象。
一个Builder类会一步步构造最终的对象,该Builder类是独立于其他对象的。
意图:将一个复杂的构建与其表示相分离,使同样的构建过程可创建不同的表示。
主要解决:在软件系统中,有时会面临复杂的对象的创建工作,该复杂对象通常由各个部分的子对象用特定算法构成。由于需求的变化,该对象的各个部分通常会有较大变化,但将各个部分组合在一切的算法却相对稳定。
使用场景:一些基本组件不变,但他们的组合经常变化的时候。需生成的对象有复杂的内部结构,对象内部属性本身相互依赖。
关键代码:将变与不变相分离,建造者(Builder类)创建和提供实例,导演管理建造出的实例的依赖关系。
应用实例:快餐店中的套餐,单样不变,但有很多组合方式,生成了不同的套餐。
优点:建造者独立,易扩展,便于控制细节风险。
缺点:产品须有共同点,范围有限制;内部变化复杂,会有很多建造类。
注:建造者模式与工厂模式的区别是建造者模式更加注重组件之间的组合顺序。
实例
一个快餐店实例,一个套餐可以是包子或油条与豆脑或馄饨的搭配。包子或油条装在盘子中,豆脑或馄饨装在碗中。
将创建一个表示食物条目的Food接口和实现Food接口的实现类,以及一个表示容器条目的Container接口和实现Container接口的实现类。
然后创建一个TaoCan类,带有Food的ArrayList和一个通过结合Food来创建不同类型的TaoCan对象的TaoCanBuilder。
分别创建表示食物条目和容器条目的接口
食物接口
public interface Food {
//食物名称抽象方法
public String name();
//食物容器抽象方法
public Container container();
//食物价格抽象方法
public Float price();
}
容器接口
public interface Container {
//容器名称抽象方法
public String container();
}
创建实现容器接口的实体类
Bowl类
public class Bowl implements Container {
public String container() {
return "碗";
}
}
Dish类
public class Dish implements Container {
public String container() {
return "盘子";
}
}
创建实现Food接口的抽象类,该类提供了默认的功能
食品Eat类
public abstract class Eat implements Food {
public Container container() {
return new Dish();
}
public abstract Float price();
}
汤Soup类
public abstract class Soup implements Food {
public Container container() {
return new Bowl();
}
public abstract Float price();
}
创建扩展了Eat和Soup的实体类
扩展了Eat的包子BaoZi类
public class BaoZi extends Eat {
public String name() {
return "包子";
}
public Float price() {
//包子价格两块五一个
return 2.5F;
}
}
扩展了Eat的油条YouTiao类
public class YouTiao extends Eat {
public String name() {
return "油条";
}
public Float price() {
//油条价格两块一根
return 2.0F;
}
}
扩展了Soup的馄饨HunTun类
public class HunTun extends Soup {
public String name() {
return "馄饨";
}
public Float price() {
//馄饨价格四块五一碗
return 4.5F;
}
}
扩展了Soup的豆脑DouNao类
public class DouNao extends Soup {
public String name() {
return "豆脑";
}
public Float price() {
//豆脑价格三块一碗
return 3.0F;
}
}
创建套餐类,带有上面定义的Food对象
public class TaoCan {
private List<Food> foods = new ArrayList<Food>();
public void addFood(Food food) {
foods.add(food);
}
//获取套餐总价
public Float getTotalPrice() {
Float coast = 0.0F;
for (Food food : foods) {
coast += food.price();
}
return coast;
}
public void showFoods() {
for (Food food : foods) {
System.out.println("食物:" + food.name());
System.out.println("容器:" + food.container().container());
System.out.println("价格:" + food.price() + "元")
}
}
}
创建TaoCanBuilder类,实际的Builder类负责创建TaoCan对象
public class TaoCanBuilder {
//套餐一
public TaoCan TaoCan1() {
TaoCan taocan = new TaoCan();
taocan.addFood(new BaoZi());
taocan.addFood(new HunTun());
//包子馄饨套餐
return taocan;
}
//套餐二
public TaoCan TaoCan2() {
TaoCan taocan = new TaoCan();
taocan.addFood(new YouTiao());
taocan.addFood(new DouNao());
//油条豆脑套餐
return taocan;
}
}
创建实例类,使用TaoCanBuilder演示创建者模式
public class BuilderPatternDemo {
public static void main(String[] args) {
TaoCanBuilder tBuilder = new TaoCanBuilder();
TaoCan taocan1 = tBuilder.TaoCan1();
System.out.println("套餐一:");
taocan1.showFoods();
System.out.println("共花费:" + taocan1.getTotalPrice() + "元");
TaoCan taocan2 = tBuilder.TaoCan2();
System.out.println("套餐二:");
taocan2.showFoods();
System.out.println("共花费:" + taocan2.getTotalPrice() + "元");
}
}
输出结果