您的位置:首页 > 其它

【23种设计模式专题】四 建造者模式

2020-05-06 04:20 483 查看

程序猿学社的GitHub,欢迎Star
github技术专题
本文已记录到github

文章目录

  • 建造者模式
  • 前言

    通过上一章的学习,我们已经知道原型模式的浅克隆和深克隆,本文来了解一下建造者模式

    定义

    • 建造者模式属于创建型模式,建造者模式是23种设计模式的一种,将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示,它提供了一种创建对象的最佳方式。

    建造者关系:

    • Product(产品):具体产品对象
    • builder(抽象建造者) : 创建一个产品各个部件的接口
    • ConcreteBuilder(具体建造者): 实现抽象建造者对应的接口
    • Director(指挥者): 创建一个复杂的对象,控制具体的流程

    隔壁老王: “社长,你这是说啥咯,看的我一脸懵逼,不知道你说的啥。”
    社长: “别急,我们通过一个简单的案例,更好的理解什么是创建型模式”

    需求

    在小公司待过的朋友,应该深有感触,一个人负责需求、前端、后端、测试、部署等等职位。

    随着业务不断扩展,老王的就职的公司,开发的效率越来越低,严重影响交付给用户的时间,老王的boss,想了想,这样下去,公司离倒闭越来越远,参考大公司开发的流程,一个只负责一个职位,专岗专职,开发的流程实现流程规范化。
    分为:

    • 需求分析
    • 架构设计
    • 概要设计
    • 集成测试

    传统方式

    抽象接口

    package com.cxyxs.designmode.createtype;
    
    /**
    * Description:
    * Author: 程序猿学社
    * Date:  2020/5/5 17:03
    * Modified By:
    */
    public abstract class AbstractProject {
    public  abstract void demand();  //需求分析
    public  abstract void framework();  //架构设计
    public  abstract void outline();  //概要设计
    public  abstract void test();  //集成测试
    
    public  void project(){
    demand();
    framework();
    outline();
    test();
    }
    }
    • 把每个流程抽取成一个个方法,再定义一个project方法,来定义流程的先后顺序。

    具体接口实现

    package com.cxyxs.designmode.createtype;
    
    /**
    * Description:
    * Author: 程序猿学社
    * Date:  2020/5/5 17:08
    * Modified By:
    */
    public class OAProject extends AbstractProject{
    @Override
    public void demand() {
    System.out.println("OA 需求阶段...");
    }
    
    @Override
    public void framework() {
    System.out.println("OA 架构设计阶段...");
    }
    
    @Override
    public void outline() {
    System.out.println("OA 概要设计阶段...");
    }
    
    @Override
    public void test() {
    System.out.println("OA 集成测试阶段...");
    }
    }
    package com.cxyxs.designmode.createtype;
    
    /**
    * Description:
    * Author: 程序猿学社
    * Date:  2020/5/5 17:10
    * Modified By:
    */
    public class VideoProject extends  AbstractProject {
    
    @Override
    public void demand() {
    System.out.println("实景视频 需求阶段...");
    }
    
    @Override
    public void framework() {
    System.out.println("实景视频 架构设计阶段...");
    }
    
    @Override
    public void outline() {
    System.out.println("实景视频 概要设计阶段...");
    }
    
    @Override
    public void test() {
    System.out.println("实景视频 集成测试阶段...");
    }
    }

    测试接口

    package com.cxyxs.designmode.createtype;
    
    /**
    * Description:
    * Author: 程序猿学社
    * Date:  2020/5/5 17:12
    * Modified By:
    */
    public class Client {
    public static void main(String[] args) {
    OAProject project = new OAProject();
    project.project();
    System.out.println("---------------");
    VideoProject project1 = new VideoProject();
    project1.project();
    }
    }

    • 产品(项目)和产品建造的过程(做项目的过程)耦合性太高, 不利于扩展和维护。

    隔壁老王: “那如何实现产品和产品建造的解耦?”
    社长: “使用建造者模块,看看通过建造者模式的代码和传统方式两者的区别”

    建造者模式

    产品

    package com.cxyxs.designmode.createtype.build;
    
    import lombok.Data;
    
    /**
    * Description:产品
    * Author: 程序猿学社
    * Date:  2020/5/5 20:19
    * Modified By:
    */
    @Data
    public class Project {
    private  String demand;
    private  String  framework;
    private  String  outline;
    private  String  test;
    }

    builder(抽象建造者)

    package com.cxyxs.designmode.createtype.build;
    
    /**
    * Description:
    * Author: 程序猿学社
    * Date:  2020/5/5 20:18
    * Modified By:
    */
    public abstract class Builder {
    protected Project project=new Project();
    
    public  abstract void demand();  //需求分析
    public  abstract void framework();  //架构设计
    public  abstract void outline();  //概要设计
    public  abstract void test();  //集成测试
    
    /**
    * 得到产品
    * @return
    */
    public   Project getProject(){
    return  project;
    };
    }

    ConcreteBuilder(具体建造者)

    package com.cxyxs.designmode.createtype.build;
    
    /**
    * Description:
    * Author: 程序猿学社
    * Date:  2020/5/5 20:25
    * Modified By:
    */
    public class OAConcreteBuilder extends Builder {
    
    @Override
    public void demand() {
    project.setDemand("OA 需求阶段...");
    System.out.println("OA 需求阶段...");
    }
    
    @Override
    public void framework() {
    project.setDemand("OA 架构设计阶段...");
    System.out.println("OA 架构设计阶段...");
    }
    
    @Override
    public void outline() {
    project.setOutline("OA 概要设计阶段...");
    System.out.println("OA 概要设计阶段...");
    }
    
    @Override
    public void test() {
    project.setTest("OA 集成测试阶段...");
    System.out.println("OA 集成测试阶段...");
    }
    
    @Override
    public Project getProject() {
    return super.getProject();
    }
    }
    • 如果新增一个具体的VideoConcreteBuilder具体建造者,代码类似。

    Director(指挥者)

    package com.cxyxs.designmode.createtype.build;
    
    /**
    * Description:
    * Author: 程序猿学社
    * Date:  2020/5/5 20:33
    * Modified By:
    */
    public class Director {
    public  Project build(Builder builder){
    builder.demand();
    builder.framework();
    builder.outline();
    builder.test();
    return  builder.getProject();
    };
    }
    • 指挥者设置流程的先后顺序,返回具体产品

    测试类

    package com.cxyxs.designmode.createtype.build;
    
    /**
    * Description:
    * Author: 程序猿学社
    * Date:  2020/5/5 20:36
    * Modified By:
    */
    public class Client {
    public static void main(String[] args) {
    //具体建造者
    Builder builder = new OAConcreteBuilder();
    //指挥者(项目经理)
    Director director = new Director();
    //得到具体产品
    Project project = director.build(builder);
    System.out.println(project.toString());
    }
    }


    社长: “到这里,建造者的demo已经写完咯,老王,对建造者模式4者的关系,有一个大致的了解。”
    隔壁老王: “有的,社长”
    社长: “那我们来根据UML图梳理一下对应的关系”

    • Project(产品):也就是我们的OA项目,经过需求、架构设计、概要设计、集成测试这些过程后,得到的最终的项目(产品)。
    • Builder(抽象建造者): 创建一个产品,各个零部件涉及的接口。可以理解为项目负责人,定义每个阶段,我们应该输出那些内容。
    • ConcreteBuilder(具体建造者): 实现抽象建造者接口,构造各个零部件。
      -Director(指挥者):用来创建一个复杂的对象(产品),并针对性的设计具体的流程(项目经理或者公司的boss),中间的流程,指挥者可自定义。

    建造者优点:

    • 把产品和产品各个零部件组装的流程分离开来,实现了程序的解耦,方便后期进行维护和扩展。
    • 把产品内部的组装过程和细节,进行了封装。可以这样理解,作为公司的大boss,只需要了解,公司各个项目的具体进展情况,无需关注,这个项目,从0到1详细的一个过程。

    缺点:

    • 使用建造者模式,产品之间应有一定的共性,会有限制。
    • 如果内部变化复杂,会有很多的建造类,会造成脓肿。

    原创不易,不要白嫖,觉得有用的社友,给我点赞,让更多的老铁看到这篇文章。
    因技术能力有限,如文中有不合理的地方,希望各位大佬指出,在下方评论留言,谢谢,希望大家一起进步,一起成长。

    作者:程序猿学社
    原创公众号:『程序猿学社』,专注于java技术栈,分享java各个技术系列专题,以及各个技术点的面试题。
    原创不易,转载请注明来源(注明:来源于公众号:程序猿学社, 作者:程序猿学社)。

    程序猿学社 博客专家 原创文章 293获赞 2403访问量 63万+ 关注 私信
    内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
    标签: