设计模式篇(3)——建造者模式深度阐述

3.4 建造者模式

定义:建造者模式(Builder Pattern)又叫生成器模式,实际开发中,我们所需要的对象构建时非常复杂,且有很多步骤需要处理时,这时建造者模式就很适合。比如MyBatis中的SqlSessionFactory对象的创建,我们不光要创建SqlSessionFactory本身的对象,还有完成MyBatis的全局配置文件和映射文件的加载解析操作,之后把解析出来的信息绑定在SqlSessionFactory对象中

image.png

参考MyBatis的代码

image.png
优点:

  • 封装性好,创建和使用分离;
  • 扩展性好,建造类之间独立、一定程度上解耦。
    问题:
  • 产生多余的Builder对象;
  • 产品内部发生变化,建造者都要修改,成本较大。

3.4.1 角色:

  • builder(抽象建造者):为创建一个产品对象的各个部件指定抽象接口。
  • ConcreteBuilder(具体的建造者):实现Builder的接口以构造和装配该产品的各个部件,定义并明确它所创建的表示,并提供一个检索产品的接口。
  • Director(指挥者):构造一个使用Builder接口的对象。它主要有两个作用,一是:隔离了客户与对象的生产过程,二是:负责控制产品对象的生产过程。
  • Product(产品类):表示被构造的复杂对象。ConcreteBuilder创建该产品的内部表示并定义它的装配过程,包含定义组成部件的类,包括将这些部件装配成最终产品的接口。

3.4.2 使用场景

  • 产品类非常的复杂,或者产品类中的调用顺序不同产生了不同的效能
  • 多个部件或者零件,都可以装配到一个对象中,但是产生的结果又不相同
  • 当时初始化一个对象特别复杂,参数多,而且很多参数都具有默认值时
  • 在对象创建过程中会使用到系统中的一些其它对象,这些对象在产品对象的创建过程中不易得到(需要多行代码)。

3.3.3 代码实现

/**
 * @Description 学习抽象类  (产品类)
 * @Auther 九止
 * Date 2022/10/3 16:46
 */
public abstract class Study {
    /**
     * 学习顺序参数
     */
    private ArrayList<String> sequence = new ArrayList<>();

    /**
     * 看书学习
     */
    public abstract void studyByBook();

    /**
     * 看视频学习
     */
    public abstract void studyByVideo();

    /**
     * 刷题
     */
    public abstract void brushQuestion();

    /**
     * 复习
     */
    public abstract void review();

    /**
     * 执行学习计划
     */
    final public void execute() {
        this.sequence.forEach(item->{
            switch(item)
            {
                case "studyByBook":
                    this.studyByBook();
                    break;
                case "studyByVideo":
                    this.studyByVideo();
                    break;
                case "brushQuestion":
                    this.brushQuestion();
                    break;
                case "review":
                    this.review();
                    break;
                default:
                    throw new RuntimeException("提示:学习计划有误!");
            }
        });
    }

    public ArrayList<String> getSequence() {
        return sequence;
    }

    public void setSequence(ArrayList<String> sequence) {
        this.sequence = sequence;
    }
}

//=============================================================================

/**
 * @Description 英语学习类  (产品类)
 * @Auther 九止
 * Date 2022/10/3 17:01
 */
public class EnglishStudy extends Study{
    @Override
    public void studyByBook() {
        System.out.println("开始通过看书学习英语……");
    }

    @Override
    public void studyByVideo() {
        System.out.println("开始通过看视频学习英语……");
    }

    @Override
    public void brushQuestion() {
        System.out.println("开始通过刷题学习英语……");
    }

    @Override
    public void review() {
        System.out.println("开始通过复习学习英语……");
    }
}

//=============================================================================

/**
 * @Description 数学学习类  (产品类)
 * @Auther 九止
 * Date 2022/10/3 17:01
 */
public class MathStudy extends Study{
    @Override
    public void studyByBook() {
        System.out.println("开始通过看书学习数学……");
    }

    @Override
    public void studyByVideo() {
        System.out.println("开始通过看视频学习数学……");
    }

    @Override
    public void brushQuestion() {
        System.out.println("开始通过刷题学习数学……");
    }

    @Override
    public void review() {
        System.out.println("开始通过复习学习数学……");
    }
}

/**
 * @Description 学习计划抽象建造者  (抽象建造者) 在该类中提供设置产品类各个属性的方法
 * @Auther 九止
 * Date 2022/10/3 16:29
 */
public interface StudyPlanBuilder{
    /**
     * 设置学习顺序
     * @param sequence
     */
    void setSequence(ArrayList<String> sequence);

    /**
     * 获取学习对象
     * @return
     */
    Study getStudy();
}

//=============================================================================

/**
 * @Description 英语学习计划建造者
 * @Auther 九止
 * Date 2022/10/3 17:04
 */
public class EnglishStudyPlanBuilder implements StudyPlanBuilder{
    private EnglishStudy englishStudy = new EnglishStudy();

    @Override
    public void setSequence(ArrayList<String> sequence) {
        englishStudy.setSequence(sequence);
    }

    @Override
    public Study getStudy() {
        return this.englishStudy;
    }
}

//=============================================================================

/**
 * @Description 数学学习计划建造者
 * @Auther 九止
 * Date 2022/10/3 17:04
 */
public class MathStudyPlanBuilder implements StudyPlanBuilder{
    private MathStudy mathStudy = new MathStudy();

    @Override
    public void setSequence(ArrayList<String> sequence) {
        mathStudy.setSequence(sequence);
    }

    @Override
    public Study getStudy() {
        return this.mathStudy;
    }
}



/**
 * @Description 学生类充当指挥者的角色 (指挥者)
 * @Auther 九止
 * Date 2022/10/3 17:13
 */
public class Student {
    private final ArrayList<String> sequence = new ArrayList<>();
    private final EnglishStudyPlanBuilder englishStudyPlanBuilder = new EnglishStudyPlanBuilder();
    private final MathStudyPlanBuilder mathStudyPlanBuilder = new MathStudyPlanBuilder();
    private static final String STUDY_BY_BOOK = "studyByBook";
    private static final String REVIEW = "review";
    private static final String STUDY_BY_VIDEO = "studyByVideo";
    private static final String BRUSH_QUESTION = "brushQuestion";

    /**
     * 英语学习计划A
     */
    public EnglishStudy englishPlanA() {
        this.sequence.clear();
        this.sequence.add(STUDY_BY_BOOK);
        this.sequence.add(REVIEW);
        this.sequence.add(STUDY_BY_VIDEO);
        this.sequence.add(BRUSH_QUESTION);
        this.englishStudyPlanBuilder.setSequence(this.sequence);
        return (EnglishStudy) this.englishStudyPlanBuilder.getStudy();
    }

    /**
     * 英语学习计划B
     */
    public EnglishStudy englishPlanB() {
        this.sequence.clear();
        this.sequence.add(STUDY_BY_BOOK);
        this.sequence.add(STUDY_BY_VIDEO);
        this.sequence.add(BRUSH_QUESTION);
        this.sequence.add(REVIEW);
        this.englishStudyPlanBuilder.setSequence(this.sequence);
        return (EnglishStudy) this.englishStudyPlanBuilder.getStudy();
    }


    /**
     * 数学学习计划A
     */
    public MathStudy mathPlanA() {
        this.sequence.clear();
        this.sequence.add(STUDY_BY_BOOK);
        this.sequence.add(REVIEW);
        this.sequence.add(STUDY_BY_VIDEO);
        this.sequence.add(BRUSH_QUESTION);
        this.mathStudyPlanBuilder.setSequence(this.sequence);
        return (MathStudy) this.mathStudyPlanBuilder.getStudy();
    }

    /**
     * 数学学习计划B
     */
    public MathStudy mathPlanB() {
        this.sequence.clear();
        this.sequence.add(STUDY_BY_BOOK);
        this.sequence.add(STUDY_BY_VIDEO);
        this.sequence.add(BRUSH_QUESTION);
        this.sequence.add(REVIEW);
        this.mathStudyPlanBuilder.setSequence(this.sequence);
        return (MathStudy) this.mathStudyPlanBuilder.getStudy();
    }

}

public class Test {
    public static void main(String[] args) {
        Student student = new Student();
        student.mathPlanA().execute();
        System.out.println("-------------------------");
        student.englishPlanB().execute();
    }
}

3.4.4 与工厂模式对比

  • 建造者模式更加注重方法的调用顺序,工厂模式注重于创建对象。
  • 杂的部件组成,工厂模式创建出来的都一样。
  • 关注点不一样,工厂模式只需要把对象创建出来就行了,而建造者模式不仅要创建出这个对象,还要知道这个对象由哪些部分组成。
  • 建造者模式根据建造过程中的顺序不一样,最终的对象部件组成也不一样。

引用了马士兵邓澎波老师笔记的部分原文

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值