创建性-构造者设计模式

前言

      我们在使用Retrofit等这些第三方框架的时候,发现他们的使用都很方便,比如Retrofit retrofit = new Retrofit.Builder().build(),和我们通常直接new一个对象不同,他是交给Builder类,通过build()函数来构造一个Retrofit对象。

      刚开始使用,可能不太明白,明明可以直接new出来,为什么要交给Builder来构造呢?那么通过学习了构造者设计模式,才明白,原来当使用者构造对象时,构造函数的参数一般大于等于五个,就可以考虑使用构造者设计模式,这样编写代码的好处,在于结构清晰,也易于扩展。

     在实际工作中,我们可能接触了很多这种链式创建对象的场景,比如AlertDialog,发现这种代码在使用的时候,真的很香,不仅实现了参数传递的灵活性,也避免了因参数过多造成的混乱。总之,除了使用官方封装的这些类以外,自己在实现代码的同时,也想要动手实现一个建造者设计模式。

 实现

    下面我们以电脑为例,创建一个抽象类Computer,我们想想,电脑都有什么属性,品牌,型号,操作系统,用途,类型,名字等等。这些属性如果都用构造方法实现的话,会很长,而且也不易于扩展,不够灵活。

 static class Computer{String name;String brand;String os;String display;String type;String use;public void setName(String name) {this.name = name;}public void setBrand(String brand) {this.brand = brand;}public void setOs(String os) {this.os = os;}public void setDisplay(String display) {this.display = display;}public void setType(String type) {this.type = type;}public void setUse(String use) {this.use = use;}}

     比如,我们需要创造一个macbook笔记本,用传统思维,直接创造一个类,然后继承Computer,通过构造函数的方法重载,完成各种需求的笔记本。这样一套下来,代码臃肿不说,也不宜与后期的维护,如果有新的属性,又要重载一个构造函数,比较繁琐。

    static class MacBook extends Computer{public MacBook() {}// ……//各种构造函数// ……        @Overridepublic String toString() {return "MacBook{" +"name='" + name + '\'' +", brand='" + brand + '\'' +", os='" + os + '\'' +", display='" + display + '\'' +", type='" + type + '\'' +", use='" + use + '\'' +'}';}}

    如果有一个专门的类,来创建不同需求的笔记本,这个问题就能很好的解决。

    那么这个专门的类就是Builder类,通过构造者设计模式进行优化,我们这里具体到了MacBook笔记本,在实际开发工作中,这个可以使用泛型T代替,更加灵活。

 static abstract class Builder {abstract MacBookBuilder builderName(String name);abstract MacBookBuilder builderBrand(String brand);abstract MacBookBuilder builderOs(String os);abstract MacBookBuilder builderType(String type);abstract MacBookBuilder builderUse(String use);abstract MacBookBuilder builderDisPlay(String display);abstract Computer build();}

  接下来,我们将利用MacBookBuilder 来构造笔记本,代码如下:

 static class MacBookBuilder extends Builder{MacBook macBook = new MacBook();@OverrideMacBookBuilder builderName(String name) {macBook.name = name;return this;}@OverrideMacBookBuilder builderBrand(String brand) {macBook.brand = brand;return this;}@OverrideMacBookBuilder builderOs(String os) {macBook.os = os;return this;}@OverrideMacBookBuilder builderType(String type) {macBook.type = type;return this;}@OverrideMacBookBuilder builderUse(String use) {macBook.use = use;return this;}@OverrideMacBookBuilder builderDisPlay(String display) {macBook.display = display;return this;}@OverrideComputer build() {return macBook;}}

好了,我们通过测试类,测试一下,附上完整代码:

package com.example.lib;public class BuilderTest {public static void main(String[] args) {Computer macbook = new MacBookBuilder().builderName("macbook 2023").builderOs("mac/os").builderBrand("apple").builderType("Laptops").builderDisPlay("Retina显示器").builderUse("studyProgram").build();System.out.println(macbook.toString());}static class Computer{String name;String brand;String os;String display;String type;String use;public void setName(String name) {this.name = name;}public void setBrand(String brand) {this.brand = brand;}public void setOs(String os) {this.os = os;}public void setDisplay(String display) {this.display = display;}public void setType(String type) {this.type = type;}public void setUse(String use) {this.use = use;}}static class MacBook extends Computer{public MacBook() {}@Overridepublic String toString() {return "MacBook{" +"name='" + name + '\'' +", brand='" + brand + '\'' +", os='" + os + '\'' +", display='" + display + '\'' +", type='" + type + '\'' +", use='" + use + '\'' +'}';}}static abstract class Builder {abstract MacBookBuilder builderName(String name);abstract MacBookBuilder builderBrand(String brand);abstract MacBookBuilder builderOs(String os);abstract MacBookBuilder builderType(String type);abstract MacBookBuilder builderUse(String use);abstract MacBookBuilder builderDisPlay(String display);abstract Computer build();}static class MacBookBuilder extends Builder{MacBook macBook = new MacBook();@OverrideMacBookBuilder builderName(String name) {macBook.name = name;return this;}@OverrideMacBookBuilder builderBrand(String brand) {macBook.brand = brand;return this;}@OverrideMacBookBuilder builderOs(String os) {macBook.os = os;return this;}@OverrideMacBookBuilder builderType(String type) {macBook.type = type;return this;}@OverrideMacBookBuilder builderUse(String use) {macBook.use = use;return this;}@OverrideMacBookBuilder builderDisPlay(String display) {macBook.display = display;return this;}@OverrideComputer build() {return macBook;}}
}

总结 

构造者设计模式,在安卓开放当中非常常见,也是一种创建型设计模式,类似与工厂模式,但不同于工厂模式。主要优点如下:

  • 客户端不需要理解产品的内部细节,完成了产品本身与产品创建的解耦
  • 每一个具体的建造者都相对独立,产品的创建更加的精细化
  • 增加新的具体建造者,无需修改原有的代码,符合开闭原则
  • 使用链式编程,代码上更加美观

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

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

相关文章

分布式爬虫与SOCKS5代理池的组合优势

在数据驱动的时代,网络爬虫成为了获取大量信息的重要工具。然而,随着网站反爬策略的升级,传统的单机爬虫面临着速度慢、易被封禁等问题。为了应对这些挑战,我们可以尝试将分布式爬虫与SOCKS5代理池相结合,提高爬虫的性…

2023-9-2 染色法判定二分图

题目链接&#xff1a;染色法判定二分图 #include <iostream> #include <cstring> #include <algorithm>using namespace std;const int N 100010l, M 200010;int n, m; int h[N], e[M], ne[M], idx;int color[N];void add(int a, int b) {e[idx] b, ne[id…

队列的链表实现 题目(难度1/10)

C数据结构与算法 目录 队列介绍 队列这种容器&#xff0c;就像大家排队上公交车一样。 第一个来到的人排在最前面&#xff1b; 最后来的排在最后面&#xff1b; 第一个先上车&#xff08;离开队列&#xff09;&#xff1b; 队列的接口 队列是有如下接口的容器&#xff1…

【Flutter】Flutter 使用 percent_indicator 实现基于百分比显示进度

【Flutter】Flutter 使用 percent_indicator 实现基于百分比显示进度 文章目录 一、前言二、安装和基本使用三、圆形百分比指示器四、线性百分比指示器五、完整示例六、总结 一、前言 今天我要为你介绍一个非常实用的Flutter包——percent_indicator。这个包允许我们基于百分比…

视频融合平台EasyCVR视频汇聚平台关于小区高空坠物安全实施应用方案设计

近年来&#xff0c;随着我国城市化建设的推进&#xff0c;高楼大厦越来越多&#xff0c;高空坠物导致的伤害也屡见不鲜&#xff0c;严重的影响到人们的生命安全。像在日常生活中一些不起眼的小东西如烟头、鸡蛋、果核、易拉罐&#xff0c;看似伤害不大&#xff0c;但只要降落的…

Linux上配置NAT

Linux系统上实现NAT上网是一个挑战性的任务&#xff0c;需要对操作系统进行合理的配置。本文将概述在Linux上实现NAT上网&#xff0c;并给出相应的工作步骤。 NAT&#xff0c;即Network Address Translation&#xff0c;是一种网络部署技术&#xff0c;可以在peivate network&…

​7.3 项目3 贪吃蛇(控制台版) (A)​

C自学精简实践教程 目录(必读) 主要考察 模块划分 / 文本文件读取 UI与业务分离 / 模块划分 控制台交互 / 数据抽象 需求 用户输入字母表示方向&#xff0c;实现贪吃蛇游戏 规则&#xff1a;碰到边缘和碰到蛇自己都算游戏结束 输入文件 data.txt data.txt 内容如下&am…

javaee spring aop 切入点表达式

1、切入点表达式&#xff1a;对指定的方法进行拦截&#xff0c;并且生成代理表达式。 表达式语法&#xff1a;execution([修饰符] 返回值类型 包名.类名.方法名(参数))execution( public void com.test.service.impl.UsersService.add() )2、表达式不同写法 1.匹配指定方法 …

深入探讨梯度下降:优化机器学习的关键步骤(二)

文章目录 &#x1f340;引言&#x1f340;eta参数的调节&#x1f340;sklearn中的梯度下降 &#x1f340;引言 承接上篇&#xff0c;这篇主要有两个重点&#xff0c;一个是eta参数的调解&#xff1b;一个是在sklearn中实现梯度下降 在梯度下降算法中&#xff0c;学习率&#xf…

TCP的三次握手、四次挥手

首先我们要知道建立连接的目的是什么&#xff0c;我们是为了可靠的传输数据。那既然是可靠的传输数据&#xff0c;我们必须保证客户端和服务端都能正常的发送和接收数据&#xff0c;如果某一方不能正常的发送或者接收数据&#xff0c;那整个数据的传输就不能成功&#xff0c;也…

设计模式—职责链模式(Chain of Responsibility)

目录 思维导图 什么是职责链模式&#xff1f; 有什么优点呢&#xff1f; 有什么缺点呢&#xff1f; 什么场景使用呢&#xff1f; 代码展示 ①、职责链模式 ②、加薪代码重构 思维导图 什么是职责链模式&#xff1f; 使多个对象都有机会处理请求&#xff0c;从而避免请…

应急三维电子沙盘数字孪生系统

一、简介应急三维电子沙盘数字孪生系统是一种基于虚拟现实技术和数字孪生技术的应急管理工具。它通过将真实世界的地理环境与虚拟世界的模拟环境相结合&#xff0c;实现了对应急场景的模拟、分析和决策支持。该系统主要由三维电子沙盘和数字孪生模型两部分组成。三维电子沙盘是…

Linux 学习笔记(1)——系统基本配置与开关机命令

目录 0、起步 0-1&#xff09;命令使用指引 0-2&#xff09;查看历史的命令记录 0-3&#xff09;清空窗口内容 0-4&#xff09;获取本机的内网 IP 地址 0-5&#xff09;获取本机的公网ip地址 0-6&#xff09;在window的命令行窗口中远程连接linux 0-7&#xff09;修改系…

Linux串口驱动

《I.MX6ULL 参考手册》第 3561 页的“Chapter 55 Universal Asynchronous Receiver/Transmitter(UART) I.MX6ULL串口原理 1.1UART与USART UART是异步通信&#xff0c;USART是异步/同步通信&#xff0c;比UART多了一条时钟线 USART 的全称是 Universal Synchronous/Asynchr…

抖音视频删了怎么在电脑上找回来

【昨天整理电脑文件时&#xff0c;不小心将剪辑好的抖音作品误删了&#xff0c;但是回收站中找不回来了&#xff0c;这些视频是我花了很多心血制作的&#xff0c;如果没了真的十分可惜&#xff01;希望大家能帮帮我&#xff0c;告诉我应该如何恢复这些文件。】 现在人们都喜欢…

重装Windows10系统

以前清理电脑我一般是重置电脑的&#xff0c;但是重置电脑会清理C盘&#xff0c;新系统又遗留有以前的系统文件&#xff0c;导致后面配置环境遇到了棘手的问题&#xff0c;所以我打算重装系统。 第一次重装windows10系统&#xff0c;踩了很多坑&#xff0c;搞了两天才配回原来的…

【Rust】002-基础语法:函数

【Rust】002-基础语法&#xff1a;函数 文章目录 【Rust】002-基础语法&#xff1a;函数一、概述二、函数1、基本函数2、参数3、即时补充&#xff1a;函数参数是 String 和 &str 的区别String&str对比 4、返回值语句和表达式语句块示例返回值 一、概述 在 Rust 中&…

网络编程

1. 网络编程入门 1.1 网络编程概述 计算机网络 是指将地理位置不同的具有独立功能的多台计算机及其外部设备&#xff0c;通过通信线路连接起来&#xff0c;在网络操作系统&#xff0c;网络管理软件及网络通信协议的管理和协调下&#xff0c;实现资源共享和信息传递的计算机系统…

(七)k8s实战-高级调度

一、CronJob 定时任务 1、cron 表达式 # ┌───────────── 分钟 (0 - 59) # │ ┌───────────── 小时 (0 - 23) # │ │ ┌───────────── 月的某天 (1 - 31) # │ │ │ ┌───────────── 月份 (1 - 12) # │ │ │ │ ┌…

ChatGPT AIGC 完成二八分析柏拉图的制作案例

我们先让ChatGPT来总结一下二八分析柏拉图的好处与优点 同样ChatGPT 也可以帮我们来实现柏拉图的制作。 效果如下: 这样的按年份进行选择的柏拉图使用前端可视化的技术就可以实现。 如HTML,JS,Echarts等,但是代码可以让ChatGPT来做,生成。 在ChatGPT中给它一个Prompt …