在生活中,似乎有些过程方法都可以单独拿出来去创造不一样的事物,这种过程方法就是一种建造过程,就像瓷器窑利用相同的加工流程,可以创造出不同的精美工艺品。
今天介绍的这种建造者设计模式就是一种抽离出创建对象的过程,从而根据相同的创建过程来创建不同形式和类型的对象,也被称为:生成器模式。在设计过程中,利用这种模式将对象的构造代码从产品类中抽离出去,放在一个独立的生成器或者构建器中来生成对象。接下来展开学习一下这种模式。
建造者模式定义
官方定义:将一个复杂对象的构建与其表示分离,使得相同的构建过程可以创建不同的表示。
通俗释义:将杂糅的构建复杂对象的过程抽象一下,然后将其构建的过程分离出来,利用这个构建过程可以构建出不同的业务类型。举个例子,就像电商首页,如果根据用户的不同类型,来展现不同的首页(美妆首页,母婴首页,食品首页等等),不知道例子恰当不恰当,但是主要是说明,构建的过程可以复用到不同的首页展示上。
通过上面的通用类图可以看出,建造者模式需要以下几个角色:
- Product产品类
一般实现了模板方法模式,有相应的基本方法和模板方法,参考上一篇模板方法模式,可以有多个产品子类。 - Builder抽象建造者
规范产品的创建,具体由子类实现,通常是一个抽象类。 - ConcreteBuilder具体建造者
实现抽象建造者所有基本方法,并且返回一个组建好的对象。 - Director导演类
负责安排已有模块的顺序,然后告诉Builder可以开始建造了。
建造者模式通用代码
/**
* @Description:产品类,一般可以通过模板方法模式来创造产品类
*/
public class Product {
public void method(){
//业务处理
}
}
/**
* @Description:抽象建造者
*/
public abstract class Builder {
//不一样的地方就是这个,可以根据装配要素产生不同的产品
public abstract void setPart();
public abstract Product buildProduct();
}
/**
* @Description:具体建造者,不同的产品具有不同建造者
*/
public class ConcreteBuilder extends Builder{
private Product product = new Product();
@Override
public void setPart() {
//设置产品特殊性
}
@Override
public Product buildProduct() {
return product;
}
}
/**
* @Description:主导类,起封装作用,避免高层侵入建造者内部实现
*/
public class Director {
private Builder builder = new ConcreteBuilder();
public Product getProduct(){
builder.setPart();
//设置不同的产品属性等业务逻辑
return builder.buildProduct();
}
}
以上就是建造者模式的通用代码,既然是通用代码,那么可以有很多变种,可以演化为不同的可扩展的建造者模式。建造者模式关注的是产品零部件的和装配顺序,不同的装配顺序会产生不同的产品,而与工厂模式的区别就在于工厂模式重点是创建,创造不同的零部件,至于装配过程与顺序不是工厂模式关心的。
建造者模式应用场景
有以下几种场景可以考虑使用建造者模式:
- 相同的方法,不同的执行顺序,产生不同的事件结果的情况下,可以采用建造者模式。
- 多个部件或者零件,都可以装配到一个对象中,但是产生的运行结果又不一样,这时就可以尝试采用构建者模式。
- 产品非常复杂,产品类中不同的调用顺序产生不同的效果,则采用建造者模式非常适用。
建造者模式优缺点
优点:
- 封装性。适用建造者模式的话,客户端不需要关心产品内部的实现逻辑和细节。
- 独立性。可以细化创建过程,生成不同的产品时可以复用相同的建造代码,且不对其他模块产生任何影响。
- 单一职责。将复杂的业务逻辑从产品类中抽离出来。
缺点:
需要增加较多的类,所以代码的复杂度较高。
建造者模式经典应用
建造者模式是Java中的一个重要且著名的设计模式,当你在创建一个有不同的配置选项的对象的时候,都可以使用。这种模式在Java的核心类库中有广泛的应用。
java.lang.StringBuilder#append()
java.lang.StringBuffer#append()
java.lang.Appendable
还有非常多的经典应用,在阅读源码的时候多多留意就会发现。不过一般建造者模式都有一个通用的识别方法:拥有一个构建方法和多个配置结果对象的方法,一般支持通用方法链,例如:XXXBuilder->setValue1(1)->setValue2(2)->setValue3(2)->create().