23种设计模式之建造者模式
作者:互联网
23种设计模式之建造者模式
文章目录
参考资料
- Java设计模式:23种设计模式全面解析(超级详细)
- 韩顺平老师的Java设计模式(图解+框架源码剖析)
- 秦小波老师的《设计模式之禅》
下文如有错漏之处,敬请指正
一、简介
定义
建造者模式是将一个复杂对象的构建与它的表示分离,使同样的构建过程可以创建不同的表示。
特点
- 建造者模式是一种创建型设计模式。
- 客户端只要提供产品基本信息就可以获取产品而无需知道产品内部构建细节。
- 通过将构建过程抽离出来,可以对有着相同构建步骤的产品进行扩展。
通用类图
在建造者模式中,有如下5个角色:
-
Product
产品类
一个复杂的产品
-
Builder
建造者(抽象类或接口)
构建Product的抽象步骤(相当于拆分成各个部分),由每一个
buildpart()
方法建造每个部分 -
ConcreteBuilder
具体产品建造者(实现Builder)
实现具体产品的构建过程,实现Builder的所有方法
-
Director
指挥者(聚合Builder)
与Client直接沟通,根据Client的需求传入相应的ConcreteBuilder进行组装,由
construct()
方法进行组装,并返回组建好的产品 -
Client
客户端
客户端不关心产品的构造细节,直接向Director提供产品的基本信息来获取产品。
优点
● 封装性
使用建造者模式可以使客户端不必知道产品内部组成的细节。
● 建造者独立,容易扩展
XConcreteBuilder和YConcreteBuilder是相互独立的,当需要新的(同样构造过程)产品时,只需要添加一个新的ConcreteBuilder。
● 便于控制细节风险
由于具体的建造者是独立的,因此可以对建造过程逐步细化,而不对其他的模块产生任何影响。
应用场景
- 如果一个对象的构建很复杂,需要很多步骤,则考虑使用建造者模式,把对象的构建和最后的组装分离开来。
- 相同的方法,不同的执行顺序,产生不同的事件结果时,可以采用建造者模式。
- 在平常使用的类中如果后缀为builder则就是建造者模式。
- StringBuilder类的apend方法。
- SQL中的PreparedStatement。
二、建造者模式
需求:
客户端需要一台奔驰C级轿车和一台奔驰S级轿车,指挥者了解了基本信息后,向建造者下达生产命令,由具体建造者实施命令,最终返回相应的产品。
Product:产品,定义奔驰汽车的基本信息。Benz(奔驰汽车)
Component:组件,奔驰起床建造需要的零件。BenzEngine(奔驰引擎) BenzTire(奔驰轮胎)BenzSteeringWheel(奔驰方向盘)BenzFrame(奔驰汽车框架)
Builder:抽象建造者,定义奔驰汽车建造的过程。BenzBuilder(奔驰起床抽象建造者)
ConcreteBuilder:具体建造者,实现当前奔驰级别汽车的生产。BenzCarCBuilder(奔驰C级汽车建造者)BenzCarSBuilder(奔驰S级汽车建造者)
Director:指挥者,根据客户端的要求指挥生产相应的产品。BenzDirector(奔驰汽车指挥者)
Client:向指挥者传递产品的基本信息获取产品。
Product:
package builder;
public class Benz {
private BenzEngine benzEngine;
private BenzTire benzTire;
private BenzSteeringWheel benzSteeringWheel;
private BenzFrame benzFrame;
public BenzEngine getBenzEngine() {
return benzEngine;
}
public void setBenzEngine(BenzEngine benzEngine) {
this.benzEngine = benzEngine;
}
public BenzTire getBenzTire() {
return benzTire;
}
public void setBenzTire(BenzTire benzTire) {
this.benzTire = benzTire;
}
public BenzSteeringWheel getBenzSteeringWheel() {
return benzSteeringWheel;
}
public void setBenzSteeringWheel(BenzSteeringWheel benzSteeringWheel) {
this.benzSteeringWheel = benzSteeringWheel;
}
public BenzFrame getBenzFrame() {
return benzFrame;
}
public void setBenzFrame(BenzFrame benzFrame) {
this.benzFrame = benzFrame;
}
}
Component:
package builder;
public class BenzEngine {
public String name;
public BenzEngine(String name) {
this.name = name;
}
}
package builder;
public class BenzFrame {
public String name;
public BenzFrame(String name) {
this.name = name;
}
}
package builder;
public class BenzSteeringWheel {
public String name;
public BenzSteeringWheel(String name) {
this.name = name;
}
}
package builder;
public class BenzTire {
public String name;
public BenzTire(String name) {
this.name = name;
}
}
Builder:
package builder;
public interface BenzBuilder {
public void buildBenzTire();
public void buildBenzSteeringWheel();
public void buildBenzEngine();
public void buildBenzFrame();
public Benz build();
}
ConcreteBuilder:
package builder;
public class BenzCarCBuilder implements BenzBuilder {
Benz benzCar=new Benz();
@Override
public void buildBenzTire() {
benzCar.setBenzTire(new BenzTire("奔驰C级汽车轮胎"));
System.out.println("正在生产奔驰C级汽车轮胎");
}
@Override
public void buildBenzSteeringWheel() {
benzCar.setBenzSteeringWheel(new BenzSteeringWheel("奔驰C级汽车方向盘"));
System.out.println("正在生产奔驰C级汽车方向盘");
}
@Override
public void buildBenzEngine() {
benzCar.setBenzEngine(new BenzEngine("奔驰C级汽车引擎"));
System.out.println("正在生产奔驰C级汽车引擎");
}
@Override
public void buildBenzFrame() {
benzCar.setBenzFrame(new BenzFrame("奔驰C级汽车框架"));
System.out.println("正在生产奔驰C级汽车框架");
}
@Override
public Benz build() {
return benzCar;
}
}
package builder;
public class BenzCarSBuilder implements BenzBuilder {
Benz benzCar=new Benz();
@Override
public void buildBenzTire() {
benzCar.setBenzTire(new BenzTire("奔驰S级汽车轮胎"));
System.out.println("正在生产奔驰S级汽车轮胎");
}
@Override
public void buildBenzSteeringWheel() {
benzCar.setBenzSteeringWheel(new BenzSteeringWheel("奔驰S级汽车方向盘"));
System.out.println("正在生产奔驰S级汽车方向盘");
}
@Override
public void buildBenzEngine() {
benzCar.setBenzEngine(new BenzEngine("奔驰S级汽车引擎"));
System.out.println("正在生产奔驰S级汽车引擎");
}
@Override
public void buildBenzFrame() {
benzCar.setBenzFrame(new BenzFrame("奔驰S级汽车框架"));
System.out.println("正在生产奔驰S级汽车框架");
}
@Override
public Benz build() {
return benzCar;
}
}
Director:
package builder;
public class BenzDirector {
private BenzBuilder builder = null;
public BenzDirector(BenzBuilder builder) {
this.builder = builder;
}
// 指挥者可以根据需求调整构建步骤(顺序)
public Benz construct() {
builder.buildBenzEngine();
builder.buildBenzFrame();
builder.buildBenzTire();
builder.buildBenzSteeringWheel();
return builder.build();
}
}
Client:
package builder;
public class Client {
public static void main(String[] args) {
//模拟用户跟指挥者说了要奔驰C级汽车,然后传入C级汽车的建造者
Benz benzC = new BenzDirector(new BenzCarCBuilder()).construct();
System.out.println("=======================");
//模拟用户跟指挥者说了要奔驰S级汽车,然后传入S级汽车的建造者
Benz benzS = new BenzDirector(new BenzCarSBuilder()).construct();
/**
* 输出结果:
* 正在生产奔驰C级汽车引擎
* 正在生产奔驰C级汽车框架
* 正在生产奔驰C级汽车轮胎
* 正在生产奔驰C级汽车方向盘
* =======================
* 正在生产奔驰S级汽车引擎
* 正在生产奔驰S级汽车框架
* 正在生产奔驰S级汽车轮胎
* 正在生产奔驰S级汽车方向盘
*/
}
}
三、 建造者模式与抽象工厂模式的区别
- 建造者模式返回一个组装好的完整产品,而抽象工厂模式返回一系列相关的产品。
- 建造者模式侧重产品的构建过程(顺序),抽象工厂侧重产品的获取过程。
- 抽象工厂模式好比一个配件工厂,建造者模式则是一个组装工厂。
四、总结
- 建造者模式是用来扩展同样构建过程的不同产品
- 产品类非常复杂,或者产品类中的调用顺序不同产生了不同的效能,这个时候使用建造者模式(结合模板模式)非常合适。
标签:name,23,builder,建造,奔驰,void,设计模式,public 来源: https://blog.csdn.net/space_qi/article/details/113083043