架构师内功心法,注重方法调用顺序的建造者模式详解
建造者模式适用于创建对象需要很多步骤,但是步骤的顺序不是固定不变的。先看一下建造者模式的类图:
建造者模式中的四个重要角色:
- 产品(Product):要创建的产品类对象
- 抽象建造者(Builder):规范产品对象的各个组成部分的建造
- 建造者(Concrete Builder):具体化对象的各个组成部分的创建
- 调用者(Director):负责保证对象各部分完整创建或按某种顺序创建
二、建造者模式的应用场景
建造者模式适用于一个具有较多的零件的复杂产品的创建过程,由于需求的变化,组成这个复杂产品的各个零件经常猛烈变化,但是它们的组合方式却相对稳定。
建造者模式适用于以下几种场景:
- 相同的方法,不同的执行顺序,产生的结果也不同
- 多个部件或零件,装配到一个对象中,产生的结果不同
- 产品类复杂,或者产品类中调用顺序不同产生不同的作用
- 初始化对象特别复杂,参数多,而且很多参数都有默认值
2.1 建造者模式的基本写法
我们以公司的技术培训为例,一个完整的技术培训需要由发布培训通知、制作培训PPT、组织员工培训、现场(远程)培训、提交培训问卷等步骤。下面我们用建造模式的代码来简单实现这类场景,首先创建一个技术培训的 TechnicalTraining 产品类 :
public class TechnicalTraining { private String notice;
private String ppt;
private String training;
private String questionnaire;
public String getNotice() {
return notice;
}
public void setNotice(String notice) {
this.notice = notice;
}
public String getPpt() {
return ppt;
}
public void setPpt(String ppt) {
this.ppt = ppt;
}
public String getTraining() {
return training;
}
public void setTraining(String training) {
this.training = training;
}
public String getQuestionnaire() {
return questionnaire;
}
public void setQuestionnaire(String questionnaire) {
this.questionnaire = questionnaire;
}
@Override
public String toString() {
return "TechnicalTraining{" +
"notice="" + notice + """ +
", ppt="" + ppt + """ +
", training="" + training + """ +
", questionnaire="" + questionnaire + """ +
"}";
}
}
接着创建建造者 TrainingBuilder 类,将复杂的构造过程封装起来:
public class TrainingBuilder { private TechnicalTraining technicalTraining = new TechnicalTraining();
/**
* 发布培训通知
* @param notice
*/
public void PostNotice(String notice) {
technicalTraining.setNotice(notice);
}
/**
* 制作培训PPT
*/
public void createPPT(String ppt) {
technicalTraining.setPpt(ppt);
}
/**
* 组织员工培训
*/
public void organizeTraining(String training) {
technicalTraining.setTraining(training);
}
/**
* 提交培训问卷
*/
public void sumitQuestionnaire(String questionnaire) {
technicalTraining.setQuestionnaire(questionnaire);
}
public TechnicalTraining build() {
return technicalTraining;
}
}
测试main方法:
public static void main(String[] args) {
TrainingBuilder builder = new TrainingBuilder();builder.PostNotice("发布培训通知");
builder.createPPT("创建ppt");
builder.organizeTraining("组织员工培训");
builder.sumitQuestionnaire("提交培训问卷");
System.out.println(builder.build());
}
最后来看一下类图:
2.2 建造者模式的链式写法
在平时的应用中,建造者模式通常是采用链式编程的方式构造对象,下面我们来改造上面的案例代码,将TechnicalTraining变成TrainingBuilder的内部类,将构造步骤添加进去,每完成一个步骤,都返回 this:
public class TrainingBuilder { public class TechnicalTraining {
private String notice;
private String ppt;
private String training;
private String questionnaire;
public String getNotice() {
return notice;
}
public void setNotice(String notice) {
this.notice = notice;
}
public String getPpt() {
return ppt;
}
public void setPpt(String ppt) {
this.ppt = ppt;
}
public String getTraining() {
return training;
}
public void setTraining(String training) {
this.training = training;
}
public String getQuestionnaire() {
return questionnaire;
}
public void setQuestionnaire(String questionnaire) {
this.questionnaire = questionnaire;
}
}
private TechnicalTraining technicalTraining = new TechnicalTraining();
/**
* 发布培训通知
* @param notice
*/
public TrainingBuilder PostNotice(String notice) {
technicalTraining.setNotice(notice);
return this;
}
/**
* 制作培训PPT
*/
public TrainingBuilder createPPT(String ppt) {
technicalTraining.setPpt(ppt);
return this;
}
/**
* 组织员工培训
*/
public TrainingBuilder organizeTraining(String training) {
technicalTraining.setTraining(training);
return this;
}
/**
* 提交培训问卷
*/
public TrainingBuilder sumitQuestionnaire(String questionnaire) {
technicalTraining.setQuestionnaire(questionnaire);
return this;
}
public TechnicalTraining build() {
return this.technicalTraining;
}
}
测试main方法:
public static void main(String[] args) { TrainingBuilder builder = new TrainingBuilder();
builder.PostNotice("发布培训通知")
.createPPT("创建ppt")
.organizeTraining("组织员工培训")
.sumitQuestionnaire("提交培训问卷");
System.out.println(builder.build());
}
最后再来看下类图:
三、建造者模式在源码中的体现
3.1 StringBuilder类
使用StringBuilder类,我们常用的有append()、toString()方法,我们来看下append()方法的源码:
public StringBuilder(CharSequence seq) { this(seq.length() + 16);
append(seq);
}
@Override
public StringBuilder append(Object obj) {
return append(String.valueOf(obj));
}
@Override
public StringBuilder append(String str) {
super.append(str);
return this;
}
3.2 Spring中的BeanDefinitionBuilder类
比如 BeanDefinitionBuilder 通过调用 getBeanDefinition()方法获得一个 BeanDefinition 对象,比如下面的源码:
private BeanDefinitionBuilder(AbstractBeanDefinition beanDefinition) { this.beanDefinition = beanDefinition;
}
public AbstractBeanDefinition getRawBeanDefinition() {
return this.beanDefinition;
}
public AbstractBeanDefinition getBeanDefinition() {
this.beanDefinition.validate();
return this.beanDefinition;
}
四、建造者模式的优缺点
建造者模式的优点:
封装性好,创建和使用分离;
扩展性好,建造类之间独立、一定程度上解耦。
建造者模式的缺点:
产生多余的 Builder 对象;
产品内部发生变化,建造者都要修改,成本较大。
建造者模式和工厂模式的区别
通过前面的学习,我们已经了解建造者模式,那么它和工厂模式有什么区别呢?
1、建造者模式更加注重方法的调用顺序,工厂模式注重于创建对象。
2、创建对象的力度不同,建造者模式创建复杂的对象,由各种复杂的部件组成,工厂模式创建出来的都一样。
3、关注重点不一样,工厂模式模式只需要把对象创建出来就可以了,而建造者模式中不仅要创建出这个对象,还要知道这个对象由哪些部件组成。
4、建造者模式根据建造过程中的顺序不一样,最终的对象部件组成也不一样。
以上是 架构师内功心法,注重方法调用顺序的建造者模式详解 的全部内容, 来源链接: utcz.com/z/513983.html