飞道的博客

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

304人阅读  评论(0)

程序猿学社的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各个技术系列专题,以及各个技术点的面试题。
原创不易,转载请注明来源(注明:来源于公众号:程序猿学社, 作者:程序猿学社)。


转载:https://blog.csdn.net/qq_16855077/article/details/105933701
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场