设计模式(五):创建型之建造者模式

news2025/2/24 23:53:00

设计模式系列文章

设计模式(一):创建型之单例模式

设计模式(二、三):创建型之工厂方法和抽象工厂模式

设计模式(四):创建型之原型模式

设计模式(五):创建型之建造者模式

设计模式(六):结构型之代理模式


目录

  • 一、设计模式分类
  • 二、建造者模式
    • 1、概述
    • 2、结构
    • 3、实例
    • 4、优缺点
    • 5、模式扩展


一、设计模式分类

  • 创建型模式
    • 用于描述“怎样创建对象”,它的主要特点是“将对象的创建与使用分离”
    • 提供了单例、原型、工厂方法、抽象工厂、建造者 5 种创建型模式
  • 结构型模式
    • 用于描述如何将类或对象按某种布局组成更大的结构
    • 提供了代理、适配器、桥接、装饰、外观、享元、组合 7 种结构型模式
  • 行为型模式
    • 用于描述类或对象之间怎样相互协作共同完成单个对象无法单独完成的任务,以及怎样分配职责
    • 提供了模板方法、策略、命令、职责链、状态、观察者、中介者、迭代器、访问者、备忘录、解释器 11 种行为型模式

二、建造者模式

1、概述

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

在这里插入图片描述

  • 分离了部件的构造(由Builder来负责)和装配(由Director负责)
  • 建造者模式可以将部件和其组装过程分开,一步一步创建一个复杂的对象
  • 用户只需要指定复杂对象的类型就可以得到该对象,而无须知道其内部的具体构造细节
  • 这个模式适用于:某个对象的构建过程复杂的情况

2、结构

建造者(Builder)模式包含如下角色:

  • 抽象建造者类(Builder):这个接口规定要实现复杂对象的那些部分的创建,并不涉及具体的部件对象的创建
  • 具体建造者类(ConcreteBuilder):实现 Builder 接口,完成复杂产品的各个部件的具体创建方法。在构造过程完成后,提供产品的实例
  • 产品类(Product):要创建的复杂对象
  • 指挥者类(Director):调用具体建造者来创建复杂对象的各个部分,在指导者中不涉及具体产品的信息,只负责保证对象各部分完整创建或按某种顺序创建

类图如下:

在这里插入图片描述

3、实例

  • 生产自行车是一个复杂的过程,它包含了车架,车座等组件的生产
    • 车架又有碳纤维,铝合金等材质的
    • 车座有橡胶,真皮等材质
  • 对于自行车的生产就可以使用建造者模式

  • Bike是产品,包含车架,车座等组件
  • Builder是抽象建造者
  • MobikeBuilder和OfoBuilder是具体的建造者
  • Director是指挥者

类图如下:

在这里插入图片描述
具体的代码如下:

//自行车类
@Data
public class Bike {

    private String frame;//车架

    private String seat;//车座
}

// 抽象 builder 类
public abstract class Builder {
    //声明Bike类型的变量,并进行赋值
    protected Bike bike = new Bike();

    public abstract void buildFrame();

    public abstract void buildSeat();

    //构建自行车的方法
    public abstract Bike createBike();
}

//摩拜单车Builder类
public class MobileBuilder extends Builder {
    public void buildFrame() {
        bike.setFrame("碳纤维车架");
    }

    public void buildSeat() {
        bike.setSeat("真皮车座");
    }

    public Bike createBike() {
        return bike;
    }
}

//ofo单车Builder类
public class OfoBuilder extends Builder {

    @Override
    public void buildFrame() {
        mBike.setFrame("碳纤维车架");
    }

    @Override
    public void buildSeat() {
        mBike.setSeat("橡胶车座");
    }

    @Override
    public Bike createBike() {
        return mBike;
    }
}

//指挥者类
public class Director {
    //声明builder类型的变量
    private Builder builder;

    public Director(Builder builder) {
        this.builder = builder;
    }

    //组装自行车的功能
    public Bike construct() {
        builder.buildFrame();
        builder.buildSeat();
        return builder.createBike();
    }
}

//测试类
public class Client {
    public static void main(String[] args) {
        showBike(new OfoBuilder());
        showBike(new MobikeBuilder());
    }
    private static void showBike(Builder builder) {
        Director director = new Director(builder);
        Bike bike = director.construct();
        System.out.println(bike.getFrame());
        System.out.println(bike.getSeat());
    }
}

注意:

  • 上面示例是 Builder模式的常规用法
  • 指挥者类 Director 在建造者模式中具有很重要的作用
    • 它用于指导具体构建者如何构建产品
    • 控制调用先后次序
    • 并向调用者返回完整的产品类
  • 但是有些情况下需要简化系统结构,可以把指挥者类和抽象建造者进行结合
// 抽象 builder 类
public abstract class Builder {

    protected Bike mBike = new Bike();

    public abstract void buildFrame();
    public abstract void buildSeat();
    public abstract Bike createBike();
    
    public Bike construct() {
        this.buildFrame();
        this.BuildSeat();
        return this.createBike();
    }
}

4、优缺点

优点

  • 在建造者模式中,客户端不必知道产品内部组成的细节
  • 将产品本身与产品的创建过程解耦,使得相同的创建过程可以创建不同的产品对象
  • 将复杂产品的创建步骤分解在不同的方法中
  • 建造者模式很容易进行扩展。如果有新的需求,通过实现一个新的建造者类就可以完成,符合开闭原则

缺点

  • 造者模式所创建的产品一般具有较多的共同点,其组成部分相似
  • 如果产品之间的差异性很大,则不适合使用建造者模式,因此其使用范围受到一定的限制

5、模式扩展

  • 在开发中还有一个常用的使用方式,就是当一个类构造器需要传入很多参数
  • 如果创建这个类的实例,代码可读性会非常差
  • 而且很容易引入错误,此时就可以利用建造者模式进行重构

重构前代码如下:

@Data
@AllArgsConstructor
public class Phone {
    private String cpu;
    private String screen;
    private String memory;
    private String mainboard;
}

public class Client {
    public static void main(String[] args) {
        //构建Phone对象
        Phone phone = new Phone("intel","三星屏幕","金士顿","华硕");
        System.out.println(phone);
    }
}

重构后代码:

public class Phone {

    private String cpu;
    private String screen;
    private String memory;
    private String mainboard;

    //私有构造方法
    private Phone(Builder builder) {
        this.cpu = builder.cpu;
        this.screen = builder.screen;
        this.memory = builder.memory;
        this.mainboard = builder.mainboard;
    }

    public static final class Builder {
        private String cpu;
        private String screen;
        private String memory;
        private String mainboard;

        public Builder cpu(String cpu) {
            this.cpu = cpu;
            return this;
        }

        public Builder screen(String screen) {
            this.screen = screen;
            return this;
        }
        public Builder memory(String memory) {
            this.memory = memory;
            return this;
        }
        public Builder mainboard(String mainboard) {
            this.mainboard = mainboard;
            return this;
        }

        //使用构建者创建Phone对象
        public Phone build() {
            return new Phone(this);
        }
    }
}

public class Client {
    public static void main(String[] args) {
        //创建手机对象   通过构建者对象获取手机对象
        Phone phone = new Phone.Builder()
                .cpu("intel")
                .screen("三星屏幕")
                .memory("金士顿内存条")
                .mainboard("华硕主板")
                .build();

        System.out.println(phone);
    }
}

重构后的代码在使用起来更方便,某种程度上也可以提高开发效率

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/623019.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

让ChatGPT来写今年的高考作文,会得几分?

使用最新的ChatGPT4模型,做2023年全国甲卷的高考作文。 作文考试题目如下 人们因技术发展得以更好地掌控时间,但也有人因此成了时间的仆人。这句话引发了你怎样的联想与思考?请写一篇文章。 要求:选准角度,确定立意&#xff0…

promise、async事件循环机制,你是CV工程师?

在面试的过程中如果不了解promise、async事件循环机制基本就会认为你是CV工程师 首先分析 async/await 其实是基于promise实现的,async 函数其实就是把 promise 做了一个包装 promise 是es6的语法,async/await 是es7的语法糖,所以我们先来分析…

​即将开幕!​2023 年金融营销科技价值发现论坛亮点前瞻

由神策数据主办 Hi-Finance、爱设计、亚马逊云科技 协办和支持的 开放融合 引领营销 5.0 新纪元 暨 2023 年金融营销科技价值发现论坛 即将于 6 月 9-10 日在中国杭州开幕 届时百余位金融数字化从业者将共聚一堂 探讨金融业发展的新思路、新路径、新趋势 2023 年,数…

Windows电脑怎么加密文件?文件加密方法介绍

Windows作为目前使用人数最多的电脑系统,是很多人办公、生活的必要工具。那么你知道在Windows系统中该怎么样加密文件吗?下面我们就来一起了解一下。 方法一:文件夹加密超级大师 想要做好文件加密并不容易,需要保障文件加密的安全…

APP外包开发第三方登录

APP开发过程中往往需要对接第三方的登录,国内的有微信、QQ、微博等,国外的有google、facebook等账号。对接第三方账号登录SDK可以方便用户快捷登录,是APP登录功能里一项重要的特性。今天和大家分享对接流程和注意事项,希望对大家有…

三维数字沙盘交互大数据可视化GIS地理信息系统第十课

三维电子沙盘交互无人机倾斜摄影大数据可视化GIS地理信息系统第十课 设置system.ini 如下内容 Server122.112.229.220 userGisTest Passwordchinamtouch.com 该数据库中只提供 成都市火车南站附近的数据请注意,104.0648,30.61658 在SDK中自带了一个自定义的基础面…

公司规定所有接口都用 post 请求,这是为什么?

文章来源:https://www.zhihu.com/question/336797348 目录 背景 get 与 post 的区别 所有接口都用 post 请求? 背景 最近在逛知乎的时候发现一个有趣的问题:公司规定所有接口都用 post 请求,这是为什么? 看到这个问…

正在改变一切的Ai聊天机器人

ChatGPT通过Al生成的内容让我们眼花缭乱,从一个聊天机器人转化成推动一个创新时代的技术,但,也并非人人都知道,那么,你知道Chatgpt到底是什么吗? 文章目录 前言一、什么是Chatgpt?二、如何使用C…

实用性网站推荐

1、自动去除背景图,上传图片后免费生成已去除背景的图片 ,对于有抠图需求的极为友好! https://www.remove.bg/zh/upload 2、生成各种比例的图片,自动调整图片尺寸大小 https://imagestool.com/zh_CN/resize-images.html 3、符号…

腾讯云服务器远程连接登陆的方法

腾讯云服务器怎么连接登录?腾讯云服务器支持多种远程连接方法,可以使用腾讯云管理控制台自带的远程连接工具,也可以使用第三方远程连接工具,如如PuTTY、Xshell等,Linux操作系统可以SSH登录,Windows可以使用…

力扣 37. 解数独

一、题目描述 编写一个程序,通过填充空格来解决数独问题。 数独的解法需遵循如下规则: 数字 1-9 在每一行只能出现一次。数字 1-9 在每一列只能出现一次。数字 1-9 在每一个以粗实线分隔的 3x3 宫内只能出现一次。数独部分空格内已填入了数字&#xf…

优化 Three.js 渲染性能的实用技巧

个人主页: 左本Web3D,更多案例预览请点击》 在线案例 个人简介:专注Web3D使用ThreeJS实现3D效果技巧和学习案例 💕 💕积跬步以至千里,致敬每个爱学习的你。喜欢的话请三连,有问题请私信或者加微…

人工智能-实验三

第三次实验 一.实验目的 ​ 掌握分类算法的算法思想,包括朴素贝叶斯算法,决策树算法等。编写朴素贝叶斯算法进行分类操作。本实验主要是关于朴素贝叶斯算法的实现,在完成本实验时也复习了课程中学习的决策树分类算法的思想。 二.实验原理 …

武汉涉密系统集成资质申报的重点和难点浅析

企业想要申报涉密系统集成资质,首先要确定好申请的级别:涉密系统集成资质分甲级和乙级两个级别,这个一个是看公司体量,另外一个是看公司以后所承接的项目密级级别。级别确定好后还要确定申请哪个类别,涉密系统集成资质…

项目管理专业人员能力评价等级证书(CSPM)的级别介绍

2021年10月,中共中央、国务院发布的《国家标准化发展纲要》明确提出构建多层次从业人员培养培训体系,开展专业人才培养培训和国家质量基础设施综合教育。建立健全人才的职业能力评价和激励机制。由中国标准化协会(CAS)组织开展的项…

使用Go和Gin编写RESTFul API

使用Go和Gin开发RESTFul API 对应的代码仓库地址:gocode 本篇内容介绍如何使用Go和 Gin Web Framework来编写RESTFul API 服务的基础知识。如果你还对Go的基础操作不熟悉的话最好还是先看一下: 入门教程 Gin是一个Go语言的Web开发框架,它简化了构建Web应…

如何实现企业微信扫码登录?

开发内容:实现网页企业微信扫码登录 企业微信提供了OAuth的授权登录方式,可以让从企业微信终端打开的网页获取成员的身份信息,从而免去登录的环节。 企业应用中的URL链接(包括自定义菜单或者消息中的链接)&#xff0c…

新手git使用记录

文章目录 前言一、下载安装git二、使用git1.基本概念2.git初始化设置3.基本操作3.1、拉取远程仓库代码,修改后在提交3.2、新建分支,提交 总结 前言 几年前在学校还学了git怎么使用,毕业后公司用tfs,这东西真的拉,感觉…

将Apple Vision Pro和visionOS与计算机视觉结合使用

在2023年6月5日的WWDC大会上,苹果宣布推出多年来最大规模的硬件和软件组合产品。今年的“One more thing”(“还有一件事”)发布是苹果视觉专业版(Apple Vision Pro),这是一款集成了苹果生态系统的新型空间…

mybatis多数据源的SQL兼容

背景 最近公司要求支持国产数据库达梦,但达梦与PostgreSQL的语法有一些差异,需要做一些兼容操作。 操作步骤 本文采用dynamic-datasource-spring-boot-starter框架处理多数据源,多数据源配置如下spring:datasource:dynamic:primary: dm #设…