java设计模式-建造者模式

1.建造者(Builder)模式定义

  • 将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。

2.建造者模式主要优缺点

优点:

  • 各个具体的建造者相互独立,有利于系统的扩展。
  • 客户端不必知道产品内部组成的细节,便于控制细节风险。

缺点:

  • 产品的组成部分必须相同,这限制了其使用范围。
  • 如果产品的内部变化复杂,该模式会增加很多的建造者类。

建造者模式和工厂模式的关注点不同:

  建造者模式注重零部件的组装过程,而工厂方法模式更注重零部件的创建过程,但两者可以结合使用。

3.建造者模式主要角色

  • 产品角色(Product):它是包含多个组成部件的复杂对象,由具体建造者来创建其各个滅部件。
  • 抽象建造者(Builder):它是一个包含创建产品各个子部件的抽象方法的接口,通常还包含一个返回复杂产品的方法 getResult()。
  • 具体建造者(Concrete Builder):实现 Builder 接口,完成复杂产品的各个部件的具体创建方法。
  • 指挥者(Director):它调用建造者对象中的部件构造与装配方法完成复杂对象的创建,在指挥者中不涉及具体产品的信息。

4.建造者模式结构图

 5.建造者模式实现,以建造机器人为例

  • 创建机器人模型类。产品角色(Product)
package com.lw.designpattern.builder;

/**
 * @Classname Robot
 * @Description 机器人模型
 * @Author lw
 * @Date 2019-12-25 08:38
 */
public class Robot {

    /***/
    private String head;
    /** 身体 */
    private String body;
    /***/
    private String hand;
    /***/
    private String foot;

    public String getHead() {
        return head;
    }
    public void setHead(String head) {
        this.head = head;
    }
    public String getBody() {
        return body;
    }
    public void setBody(String body) {
        this.body = body;
    }
    public String getHand() {
        return hand;
    }
    public void setHand(String hand) {
        this.hand = hand;
    }
    public String getFoot() {
        return foot;
    }
    public void setFoot(String foot) {
        this.foot = foot;
    }
}
  • 创建建造机器人接口。抽象建造者(Builder)
package com.lw.designpattern.builder;

/**
 * @Classname IBuildRobot
 * @Description 建造机器人接口
 * @Author lw
 * @Date 2019-12-25 08:39
 */
public interface IBuildRobot {

    /** 建造头 */
    public void buildHead();
    /** 建造身体 */
    public void buildBody();
    /** 建造手 */
    public void buildHand();
    /** 建造脚 */
    public void buildFoot();
    /** 获取机器人结果 */
    public Robot getRobotResult();

}
  • 创建建造跳舞机器人类,实现IBuildRobot接口。具体建造者(Concrete Builder)
package com.lw.designpattern.builder;

/**
 * @Classname DanceRobotBuilder
 * @Description 建造跳舞机器人
 * @Author lw
 * @Date 2019-12-25 08:43
 */
public class DanceRobotBuilder implements IBuildRobot {

    private Robot robot;

    public DanceRobotBuilder(){
        robot = new Robot();
    }

    @Override
    public void buildHead() {
        robot.setHead("写入机械舞程序");
    }

    @Override
    public void buildBody() {
        robot.setBody("钛合金身体");
    }

    @Override
    public void buildHand() {
        robot.setHand("钛合金手");
    }

    @Override
    public void buildFoot() {
        robot.setFoot("钛合金脚");
    }

    @Override
    public Robot getRobotResult() {
        return robot;
    }
}
  • 创建指挥官类。指挥者(Director)
package com.lw.designpattern.builder;

/**
 * @Classname Director
 * @Description 指挥官
 * @Author lw
 * @Date 2019-12-25 08:45
 */
public class Director {

    public Robot createRobotByDirecotr(IBuildRobot ibr){
        ibr.buildBody();
        ibr.buildFoot();
        ibr.buildHand();
        ibr.buildHead();
        return ibr.getRobotResult();
    }

}
  • 单元测试
  /**
     * 建造者模式
     */
    @Test
    public void testBuilder(){
        Director director = new Director();
        Robot robot = director.createRobotByDirecotr(new DanceRobotBuilder());
        System.out.println(robot.getHead());
        System.out.println(robot.getBody());
        System.out.println(robot.getHand());
        System.out.println(robot.getFoot());
        System.out.println("机器人创建成功!!!");

    }

打印结果

6.建造者模式的应用场景

建造者模式创建的是复杂对象,其产品的各个部分经常面临着剧烈的变化,但将它们组合在一起的算法却相对稳定,所以它通常在以下场合使用。

  • 创建的对象较复杂,由多个部件构成,各部件面临着复杂的变化,但构件间的建造顺序是稳定的。
  • 创建复杂对象的算法独立于该对象的组成部分以及它们的装配方式,即产品的构建过程和最终的表示是独立的。

7.扩展,开源框架Mybatis中建造者模式的应用

  • Mybatis中用到的建造者模式:

  SqlSessionFactoryBuilder、XMLConfigBuilder、XMLMapperBuilder、XMLStatementBuilder、CacheBuilder等。

  • 举个读Mybatis源码的例子:

  XMLConfigBuilder读取配置文件构建出Configuration对象,然后SqlSessionFactoryBuilder使用Configuration对象作为参数,构建出SqlSessionFactory对象。

  • 分析原因

  这么做的原因是Mybatis的初始化工作较复杂,不是一个构造函数就能包括的。所以采用了分层构建方法。例如Mybatis中极其重要的Configuration对象,它庞大且复杂,初始化比较麻烦,所以使用专门的建造者XMLConfigBuilder进行构建。

原文地址:https://www.cnblogs.com/lwcode6/p/12094792.html