架构师内功心法,注重方法调用顺序的建造者模式详解

编程

建造者模式适用于创建对象需要很多步骤,但是步骤的顺序不是固定不变的。先看一下建造者模式的类图:

建造者模式中的四个重要角色:

  • 产品(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

回到顶部