一、建造者模式
1、建造者模式定义
建造者模式(Builder Pattern)的定义:指将一个复杂对象的构建过程与它的表示分离,使得同样的构建过程可以创建不同的表示,属于创建型设计模式。
2、建造者模式的结构 (1)模式的结构主要角色如下。
- 产品(Product):需要创建的产品类对象,它是包含多个组成部分的复杂对象,由具体建造者来创建其各个组成部分。
- 抽象建造者(Builder):它是一个包含创建产品各个子部件的抽象方法的接口,通常还包含一个返回复杂产品的 getResult()方法或者build()方法。
- 具体建造者(Concrete Builder):实现 Builder 接口,完成复杂产品的各个组成部分的具体创建方法。
- 指挥者(Director):调用具体的建造者,来创建对象的各个部分,在指挥者中不涉及具体产品的信息。
主要优点如下:
- 封装性好,构建和表示分离。
- 扩展性好,各个具体的建造者相互独立,有利于系统的解耦。
- 客户端不必知道产品内部组成的细节,建造者可以对创建过程逐步细化,而不对其它模块产生任何影响,便于控制细节风险。
主要缺点如下:
- 需要多创建一个 IBuilder对象。
- 如果产品的内部变化复杂,如果产品内部发生变化,则建造者也要同步修改,后期维护成本较大。
- 相同的方法,不同的执行顺序,产生不同的结果。
- 多个部件或零件,都可以装配到一个对象中,但是产生的结果又不相同。
- 产品类非常复杂,或者产品类中不同的调用顺序产生不同的作用。
- 初始化一个对象特别复杂,参数多,而且很多参数都具有默认值。
建造者模式针对复杂对象的创建,工厂模式针对简单对象的创建。细分的话,区别如下:
- 建造者模式更加注重方法的调用顺序,工厂模式注重创建对象。
- 创建对象的力度不同,建造者模式创建复杂的对象,由各种复杂的部件组成,工厂模式创建出来的对象都一样
- 关注重点不一样,工厂模式只需要把对象创建出来就可以了,而建造者模式不仅要创建出对象,还要知道对象由哪些部件组成。
- 建造者模式根据建造过程中的顺序不一样,最终对象部件组成也不一样。
代码如下:
public class BuilderPattern {
public static void main(String[] args) {
IBuilder builder = new ConcreteBuilder();
System.out.println(builder.name("zhaoyun").build());
}
}
// 产品类
class Product{
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Product{" +
"name='" + name + '\'' +
'}';
}
}
// 抽象建造者
interface IBuilder{
Product build();
IBuilder name(String name);
}
// 具体建造者
class ConcreteBuilder implements IBuilder{
private Product product = new Product();
@Override
public Product build() {
return product;
}
@Override
public ConcreteBuilder name(String name) {
product.setName(name);
return this;
}
}
使用静态内部类实现建造者模式,这种方式用的比较多。 链式写法看起来舒服。
// 产品-客厅类
public class Parlour {
private String wall; //墙
private String TV; //电视
private String sofa; //沙发
public String getWall() {
return wall;
}
public void setWall(String wall) {
this.wall = wall;
}
public String getTV() {
return TV;
}
public void setTV(String TV) {
this.TV = TV;
}
public String getSofa() {
return sofa;
}
public void setSofa(String sofa) {
this.sofa = sofa;
}
@Override
public String toString() {
return "Parlour{" +
"wall='" + wall + '\'' +
", TV='" + TV + '\'' +
", sofa='" + sofa + '\'' +
'}';
}
// 静态内部类
public static class Builder{
private Parlour parlour = new Parlour();
public Builder wall(String wall){
parlour.setWall(wall);
return this;
}
public Builder TV(String TV){
parlour.setTV(TV);
return this;
}
public Builder sofa(String sofa){
parlour.setSofa(sofa);
return this;
}
public Parlour build(){
return parlour;
}
}
测试类: 使用建造者模式倒是不难,在源码中应用也很广泛。
- Mybatis源码中的 CacheBuilder类和 SqlSessionFactoryBuilder类。
- Spring源码中的 BeanDefinaitionBuilder类。
参考文章:
- 设计模式:http://c.biancheng.net/view/1354.html
—— Stay Hungry. Stay Foolish. 求知若饥,虚心若愚。