创建性-构造者设计模式

前言

      我们在使用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.hqwc.cn/news/94685.html

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

相关文章

微服务·架构组件之注册与发现

引言 微服务架构在现代软件开发中越来越受欢迎,它通过将系统拆分为多个小型、自治的服务来提高可维护性、可扩展性和灵活性。然而随着服务数量的增多,服务之间的通信何发现变得更加复杂。本报告旨在深入探讨微服务中的注册与发现,介绍其背景…

CSS学习笔记05

CSS笔记05 定位 position CSS 属性position - 用于指定一个元素在文档中的定位方式。top,right,bottom 和 left 属性则决定了该元素的最终位置。position 有以下常用的属性值: position: static; - 默认值。指定元素使用正常的布局行为&am…

【Docker】01-Centos安装、简单使用

参考教程: https://www.bilibili.com/video/BV1Qa4y1t7YH/?p5&spm_id_frompageDriver&vd_source4964ba5015a16eb57d0ac13401b0fe77 什么是Docker? Docker是一种开源的容器化平台,用于构建、打包、部署和运行应用程序。它通过使用容…

Ctfshow nodejs

Ctfshow nodejs web334(特性)web335(特性)web336(特性)web337(特性)web338(原型链污染)web339(原型链污染)web340(原型链污染)web 341(ejs)web342(jade)web343(jade)web344(特性) web334(特性) login.js var express require(express);var router express.Router();var use…

C# 如何将使用的Dll嵌入到.exe应用程序中?

文章目录 前言详细实操简要步骤 前言 有没有想自己开发的exe保留一点神秘,不想让他人知道软件使用了哪些dll; 又或许是客户觉得一个软件里面的dll文件太多了,能不能简单一点,直接双击.exe就可以直接运行了,别搞那么多乱七八糟的。…

微信小程序 选择学期控件 自定义datePicker组件 不复杂

我的时间选择组件在common文件夹里 datePicker组件代码 html: <view class"date_bg_view"> </view> <view class"date_content"><view class"date_title"><image src"/image/icon_close_black.png" clas…

前端生成图片验证码怎么做?

##题记&#xff1a;我们实现一个功能首先想一下我们需要做哪些工作&#xff0c;比如我们需要生成一个随机的图片验证码&#xff0c;我们需要一个就是点击事件获取验证码&#xff0c;通过接口我们去获取图片路径进行渲染就行&#xff0c;这里边还要牵扯一件事情就是获取一个随机…

构建现代应用:Java中的热门架构概览

文章目录 1. 三层架构2. Spring框架3. 微服务架构4. Java EE&#xff08;Enterprise Edition&#xff09;5. 响应式架构6. 大数据架构7. 领域驱动设计&#xff08;Domain-Driven Design&#xff0c;DDD&#xff09;8. 安卓开发架构结论 &#x1f389;欢迎来到Java学习路线专栏~…

在Windows10上编译grpc工程,得到protoc.exe和grpc_cpp_plugin.exe

grpc是google于2015年发布的一款跨进程、跨语言、开源的RPC(远程过程调用)技术。使用C/S模式&#xff0c;在客户端、服务端共享一个protobuf二进制数据。在点对点通信、微服务、跨语言通信等领域应用很广&#xff0c;下面介绍grpc在windows10上编译&#xff0c;这里以编译grpc …

es5的实例__proto__(原型链) prototype(原型对象) {constructor:构造函数}

现在看这张图开始变得云里雾里&#xff0c;所以简单回顾一下 prototype 的基本内容&#xff0c;能够基本读懂这张图的脉络。 先介绍一个基本概念&#xff1a; function Person() {}Person.prototype.name KK;let person1 new Person();在上面的例子中&#xff0c; Person …

开发指导—利用CSS动画实现HarmonyOS动效(一)

注&#xff1a;本文内容分享转载自 HarmonyOS Developer 官网文档 一. CSS 语法参考 CSS 是描述 HML 页面结构的样式语言。所有组件均存在系统默认样式&#xff0c;也可在页面 CSS 样式文件中对组件、页面自定义不同的样式。请参考通用样式了解兼容 JS 的类 Web 开发范式支持的…

YOLOv5模型压缩:综述

YOLOv5模型压缩:综述 AbstractIntroduction剪枝基于ln-范数修剪模型Feature map activationBatch normalization scaling factor (BNSF)First-order derivativeMutual informationGranularity of Pruning非结构化剪枝结构化剪枝基于通道的修剪基于滤波器的修剪基于核的剪枝关于…