讲了建造者模式的定义、代码实现及优点。
定义:建造者模式又叫生成器模式,定义如下
用于在构建复杂对象时,“过程”是稳定的,“细节”不同的情况。“它主要是用于创建一些复杂的对象,这些对象内部构建间的建造顺序通常是稳定的,但对象内部的构建通常面临着复杂的变化。 ”
简单来说,就是创建一个对象的时候有具体的流程,使用建造者模式之后,可以避免在创建过程忽略了某一步,同时创建的时候也只需要关心我所创建的对象需要什么。比如在《在大话设计模式》中举了一个做菜的例子,如果所有做菜都已经会规定好的步骤,就不会出现忘记加盐的情况。
摘录自《大话设计模式》
Directror:统一规定构建的顺序
product:我需要创建的对象
Builder:构建父抽象类,包括产品和组件以及要产生的对象
CreateBuilder:不同产品的创建所需要的组件,每次扩展只需要扩展这个类即可
我用做菜为例,模拟了创建者模式,假设做菜需要严格的按照倒油、加料、装盘的流程。
- Food对应product
@Data public class Food { private String oil; private String spice; private String plate; @Override public String toString() { return "你吃到了用"+oil+"炒的"+",加了"+spice+",用"+plate+"装的食物。"; } }
- Builder中要包括产品、流程和获得产品的方法
public abstract class Builder { protected Food food = new Food(); abstract void setOil(); abstract void setSpice(); abstract void setPlate(); abstract Food createFood(); }
需要注意的是这里的food要设置为protected,让子类能够访问。
- CreateBuilder:以后要做新的菜,只需要实现这个接口。
下面是我实现的两种,以后有新的菜品,只需要实现新的类就行。
public class BlackFoodBuilder extends Builder{ @Override void setOil() { food.setOil("地沟油"); } @Override void setSpice() { food.setSpice("重盐重油"); } @Override void setPlate() { food.setPlate("纸盒"); } @Override Food createFood() { return food; } }
public class HomeFoodBuilder extends Builder{ @Override void setOil() { food.setOil("大豆油"); } @Override void setSpice() { food.setSpice("五香八角少盐少油"); } @Override void setPlate() { food.setPlate("瓷盘"); } @Override Food createFood() { return food; } }
- Directror:指定构建顺序并返回产品。
public class Director { private Builder builder; public Director(Builder builder) { this.builder = builder; } public Food buildFood(){ builder.setOil(); builder.setSpice(); builder.setPlate(); return builder.createFood(); } }
buildFood来控制顺序。
用户只需在Director中指定菜品即可
- 客户端
public class Client { public static void main(String[] args) { Director director = new Director(new BlackFoodBuilder()); Food food = director.buildFood(); System.out.println(food); Director director1 = new Director(new HomeFoodBuilder()); Food food1 = director1.buildFood(); System.out.println(food1); } }
- 运行结果
可以做链式结构,听过一个静态内部类实现,让产品类的构造器由Builder去实现,简化了客户端的编写。
public class Food { private String oil; private String spice; private String plate; private Food(Builder builder) { this.oil = builder.oil; this.spice = builder.spice; this.plate = builder.plate; } @Override public String toString() { return "你吃到了用"+oil+"炒的"+",加了"+spice+",用"+plate+"装的食物。"; } //将构建过程交给builder,最后调用构造方法 public static final class Builder{ private String oil; private String spice; private String plate; public Builder oil(String oil){ this.oil = oil; return this; } public Builder spice(String spice){ this.spice = spice; return this; } public Builder plate(String plate){ this.plate = plate; return this; } public Food build(){ return new Food(this); } } }
public class Client { public static void main(String[] args) { Food food = new Food.Builder() .oil("石油") .spice("酱油") .plate("铁桶") .build(); System.out.println(food); } }
运行结果:
建造者模式的链式编程很常见,比如StringBuilder,netty等地方都有过使用,还有在web程序写返回格式的时候也经常用到。
优点- 将一个复杂对象的创建过程封装起来
- 允许对象通过多个步骤来创建,并且可以改变过程(工厂模式)
《大话设计模式》
《Head FIrst》
黑马视频