Java设计模式二、构建者模式

一、构建者模式:

 
 

1、介绍:

建造者模式的定义是:将一个复杂对象的构造与它的表示分离使同样的构建过程可以创建不同的表示,这样的设计模式被称为建造者模式。

 
 

2、建造者模式的角色定义:

一个构建者模式包含以下几个类:

  • 导演类(Director):按照一定的顺序或者一定的需求去组装一个产品。
  • 构造者类(builder+ConcreteBuilder):提供对产品的不同个性化定制,最终创建出产品。
    其实他是:build接口+ConcreteBuilder接口实现类。正规的是先有一个接口builder,然后真正的构建是在实现类ConcreteBuilder中构建的。
  • 产品类(Product):最终的产品。

 
 

3、工厂模式和构建者模式区别:

  • 工厂模式构建出来的对象,其对象的属性都是一致的,即对象都是一样的。
  • 构建者模式可以根基你的要求定制不同属性的对象

 
 

4、为什么使用构建者模式?什么场景使用构建者模式?:

  • 在mybatis框架中,对于构建者模式使用的比较频繁。
  • 假如我们需要一个对象,一个对象的创建非常的复杂,对象中还要对象的封装,那么我们就可以使用构建者模式,将该对象的构建交给它来处理,我们使用的时候找他要一个对象就可以了。
  • 我想要一个对象,工厂模式就会创建一个对象,该对象的属性是固定的几个;而构建者模式可以通过导演类,组合不同的属性或者成员,可以构建出不同的对象。
  • 设计模式在实际的使用中使可以变化的,并不是固定的格式。

 
 

二、mybatis源码中-构建者模式解析:

 

1、MappedStatement的构建:

在mybatis中MapperBuilderAssistant类中对于MappedStatement对象的构建就是使用了构建者模式:

//利用构建者模式,去创建MappedStatement.Builder,用于创建MappedStatement对象
    MappedStatement.Builder statementBuilder = new MappedStatement.Builder(configuration, id, sqlSource, sqlCommandType)
        .resource(resource)
        .fetchSize(fetchSize)
        .timeout(timeout)
        .statementType(statementType)
        .keyGenerator(keyGenerator)
        .keyProperty(keyProperty)
        .keyColumn(keyColumn)
        .databaseId(databaseId)
        .lang(lang)
        .resultOrdered(resultOrdered)
        .resultSets(resultSets)
        .resultMaps(getStatementResultMaps(resultMap, resultType, id))
        .resultSetType(resultSetType)
        .flushCacheRequired(valueOrDefault(flushCache, !isSelect))
        .useCache(valueOrDefault(useCache, isSelect))
        .cache(currentCache);
        
		// 通过MappedStatement.Builder,构建一个MappedStatement
    	MappedStatement statement = statementBuilder.build();
  1. 在上面代码中,有一系列的属性,比如:.resource(resource)、.fetchSize(fetchSize)等,导演类通过Buld定制不同的属性(组合不同的属性),最终会产生不同属性的对象。
  2. 定制完属性之后,通过下面的build()方法,产生不同的对象。该build()方法调用的是MappedStatement对象中的build方法

 

2、SqlSessionFactory的构建:

 
需求:
在mybatis中的通过SqlSessionFactoryBuilder类中通过build()方法构建SqlSessionFactory对象,该对象的构建就采用了构建者模式:
 
导演类: 按照一定的顺序或者一定的需求去组装SqlSessionFactory。

public class MybatisSqlSessionFactoryBean implements FactoryBean<SqlSessionFactory>, InitializingBean, ApplicationListener<ApplicationEvent> {

	 protected SqlSessionFactory buildSqlSessionFactory() throws Exception {
	        final MybatisConfiguration targetConfiguration;
	        
 			final SqlSessionFactory sqlSessionFactory = new 
 				MybatisSqlSessionFactoryBuilder().build(targetConfiguration);
	}
}

 
 
构造者类:

下面是SqlSessionFactoryBuilder中build()方法:

在这里插入图片描述

 
 
产品类:

  public SqlSessionFactory build(Configuration config) {
    return new DefaultSqlSessionFactory(config);
  }

由构造器可以得知:产品类是DefaultSqlSessionFactory:

/**
 * @author Clinton Begin
 */
public class DefaultSqlSessionFactory implements SqlSessionFactory {

  private final Configuration configuration;

  public DefaultSqlSessionFactory(Configuration configuration) {
    this.configuration = configuration;
  }

  @Override
  public SqlSession openSession() {
    return openSessionFromDataSource(configuration.getDefaultExecutorType(), null, false);
  }
}

可以通过调用不同的build()的方法(参数不一样),构造出符合自己的SqlSessionFactory对象,采用的是构建者模式。

 
 

三、自己编写一个构建者模式:

需求:通过构建者模式构建自己想要的对象,即产品。

 

1、导演类:

/**
 * 导演类:测试类
 */
public class BuildDemo {
    public static void main(String[] args) {
        StudentBuild build = new StudentBuild();
        // 决定如何创建一个Student
        //构建产品一:
        Student student1 = build.age(1).name("张三").father("张老大").build();
		//构建产品二:
        Student student2 = build.age(1).name("李四").build();
        System.out.println(student);
    }
}

 
 

2、构造者类:构建器:


/**
 *  构造者类:构建器
 *
 *  注意:我们写的demo没有创建build接口,就直接使用实现类来实现构造这模式。
 */
public class StudentBuild {
    /*
        成员属性:需要构建的对象,直接new一个
     *
     */
    private  Student student=new Student();
    /**
     * 下面是构造方法
     */

    public StudentBuild id(int id){
        student.setId(id);
        return this;//返回的是StudentBuild对象
    }
    public StudentBuild name(String name){
        student.setName(name);
        return this;//返回的是StudentBuild对象
    }
    public StudentBuild age(int age){
        student.setAge(age);
        return this;//返回的是StudentBuild对象
    }
    public StudentBuild father(String fatherName){
        Father father = new Father();
        father.setName(fatherName);
        student.setFather(father);
        return this;//返回的是StudentBuild对象
    }
    /**
     * 构建对象的方法:build方法
     */
    public Student build(){
        return student;//返回的是Student对象
    }
}

 
 

3、产品类:


/**
 * 产品类
 */
public class Student {
    private int id;
    private String name;
    private int age;


    //子产品
    private Father father;


    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public Father getFather() {
        return father;
    }

    public void setFather(Father father) {
        this.father = father;
    }

    @Override
    public String toString() {
        return "Student{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", age=" + age +
                ", father=" + father +
                '}';
    }
}



//子产品类:
public class Father {
    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

 
 

4、总结分析:

1、我们的需求是:采用构建者模式,构建出不同的产品。由上面代码的我们构建出了两个产品。
2、导演类其实就是我们的测试类,即调用build()方法的类。
3、构建者类:其实就是在一个类中,对不同的属性做了一个构造方法,然后,通过一个build()方法
导演类想要组合的属性组合到一起,然后通过build()方法构造出想要的对象。
4、产品类:就是我们最终想要构造的对象。
5、该demo能够直观的让我们理解构造者模式,但是模式不是固定的代码格式,是可以变换的,这一点要记住。
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值