创建性-构造者设计模式

news2025/1/24 18:01:03

前言

      我们在使用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() {
        }
        
        // ……
        //各种构造函数
        // ……        
 
        @Override
        public 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();

       @Override
        MacBookBuilder builderName(String name) {
            macBook.name = name;
            return this;
        }

        @Override
        MacBookBuilder builderBrand(String brand) {
            macBook.brand = brand;
            return this;
        }

        @Override
        MacBookBuilder builderOs(String os) {
            macBook.os = os;
            return this;
        }

        @Override
        MacBookBuilder builderType(String type) {
            macBook.type = type;
            return this;
        }

        @Override
        MacBookBuilder builderUse(String use) {
            macBook.use = use;
            return this;
        }

        @Override
        MacBookBuilder builderDisPlay(String display) {
            macBook.display = display;
            return this;
        }

        @Override
        Computer 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() {
        }

        @Override
        public 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();

       @Override
        MacBookBuilder builderName(String name) {
            macBook.name = name;
            return this;
        }

        @Override
        MacBookBuilder builderBrand(String brand) {
            macBook.brand = brand;
            return this;
        }

        @Override
        MacBookBuilder builderOs(String os) {
            macBook.os = os;
            return this;
        }

        @Override
        MacBookBuilder builderType(String type) {
            macBook.type = type;
            return this;
        }

        @Override
        MacBookBuilder builderUse(String use) {
            macBook.use = use;
            return this;
        }

        @Override
        MacBookBuilder builderDisPlay(String display) {
            macBook.display = display;
            return this;
        }

        @Override
        Computer build() {
            return macBook;
        }
    }
}

总结 

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

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

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

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

相关文章

解决Ubuntu 或Debian apt-get IPv6问题:如何设置仅使用IPv4

文章目录 解决Ubuntu 或Debian apt-get IPv6问题:如何设置仅使用IPv4 解决Ubuntu 或Debian apt-get IPv6问题:如何设置仅使用IPv4 背景: 在Ubuntu 22.04(包括 20.04 18.04 等版本) 或 Debian (10、11、12)系统中,当你使用apt up…

JS中的new操作符

文章目录 JS中的new操作符一、什么是new?二、new经历了什么过程?三、new的过程分析四、总结 JS中的new操作符 参考:https://www.cnblogs.com/buildnewhomeland/p/12797537.html 一、什么是new? 在JS中,new的作用是通过…

【分类】分类性能评价

评价指标 1、准确率、召回率、精确率、F-度量、ROC ​ 属于各类的样本的并不是均一分布,甚至其出现概率相差很多个数量级,这种分类问题称为不平衡类问题。在不平衡类问题中,准确率并没有多大意义,我们需要一些别的指标。 ​ 通…

PYTHON知识点学习-函数(下)

🌈write in front🌈 🧸大家好,我是Aileen🧸.希望你看完之后,能对你有所帮助,不足请指正!共同学习交流. 🆔本文由 Aileen_0v0🧸 原创 CSDN首发🐒 如…

Mac安装brew、mysql、redis

mac安装brew mac安装brewmac安装mysql并配置开机启动mac安装redis并配置开机启动 mac安装brew 第一步:执行. /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"第二步:输入开机密码 第三…

element+vue table表格全部数据和已选数据联动

1.组件TableChoose <template><div class"tableChooseBox"><div class"tableRow"><div class"tableCard"><div class"tableHeadTip">全部{{ labelTitle }}</div><slot name"body" …

《奥本海默》热映,Sam Altman 会是下个他吗?

撰文&#xff1a;Nathan Gardels 来源&#xff1a;Noema 治理可能摧毁社会的技术。 图片来源&#xff1a;由无界AI生成 电影导演克里斯托弗 - 诺兰&#xff08;Christopher Nolan&#xff09;说&#xff0c;他曾与正在经历“奥本海默时刻”的人工智能科学家交谈过&#xff0c;他…

JavaScript 实现树形结构和一维数组互相转换

背景 树形结构和一维数组是开发中很容易碰到的情况&#xff0c;也是面试中很容易碰到的手撕题目 实现 一、一维数组转树形结构 FROM const source [{ id: 1, name: "张三", pid: 0 },{ id: 2, name: "李四", pid: 1 },{ id: 3, name: "王五&qu…

【【STM32--28--IO引脚的复用功能】】

STM32–28–IO引脚的复用功能 STM32的IO复用功能 何为复用? 我们先了解一下何为通用 IO端口的输入或输出是由GPIO外设控制&#xff0c;我们称之为通用 复用&#xff1a; IO端口的输入或者是输出是由其他非GPIO外设控制就像经常说的USART 由 DR寄存器进行输出 STM32的IO复用功…

Python学习教程:集合操作的详细教程

前言 大家早好、午好、晚好吖 ❤ ~欢迎光临本文章 Python中有两种可以遍历的容器类型&#xff1a; 序列类型&#xff1a;包含字符串、列表、元祖 序列类型是线性表&#xff0c;就像数组一样&#xff0c;是在内存中开辟一块连续空间&#xff0c;连续存储的&#xff0c; 那么查找…

前端vue3+ts架构

1、vue creat 项目名称 选择自定义 选择需要的依赖 选择vue3 一路enter&#xff0c;选择eslistprettier 继续enter&#xff0c;等待安装 按步骤操作&#xff0c;项目启动成功 2、vscode安装5款插件 2、代码保存自动格式化&#xff0c;保证每个开发人员代码一致&#xff0c;根目…

震惊!靠「职业骗薪」,在上海买了别墅

昨天在知乎热榜上看到一条新闻&#xff0c;震惊之余&#xff0c;也有点可叹可悲的感觉。 根据经济观察报的报道&#xff1a;职业骗薪者&#xff0c;3 年在沪买别墅&#xff0c;同时供职 16 家公司却从不上班&#xff0c;落网时她还在面试。 新闻上说&#xff1a;管悦被警察抓获…

Bert和LSTM:情绪分类中的表现

一、说明 这篇文章的目的是评估和比较 2 种深度学习算法&#xff08;BERT 和 LSTM&#xff09;在情感分析中进行二元分类的性能。评估将侧重于两个关键指标&#xff1a;准确性&#xff08;衡量整体分类性能&#xff09;和训练时间&#xff08;评估每种算法的效率&#xff09;。…

OpenCV(十六):高斯图像金字塔

目录 1.高斯图像金字塔原理 2.高斯图像金字塔实现 1.高斯图像金字塔原理 高斯图像金字塔是一种用于多尺度图像表示和处理的重要技术。它通过对图像进行多次高斯模糊和下采样操作来生成不同分辨率的图像层级&#xff0c;每个层级都是原始图像的模糊和降采样版本。 以下是高斯…

系统中出现大量不可中断进程和僵尸进程(理论)

一 进程状态 当 iowait 升高时&#xff0c;进程很可能因为得不到硬件的响应&#xff0c;而长时间处于不可中断状态。从 ps 或者 top 命令的输出中&#xff0c;你可以发现它们都处于 D 状态&#xff0c;也就是不可中断状态&#xff08;Uninterruptible Sleep&#xff09;。 R …

Python Opencv实践 - 轮廓检测

import cv2 as cv import numpy as np import matplotlib.pyplot as pltimg cv.imread("../SampleImages/map.jpg") print(img.shape) plt.imshow(img[:,:,::-1])#Canny边缘检测 edges cv.Canny(img, 127, 255, 0) plt.imshow(edges, cmapplt.cm.gray)#查找轮廓 #c…

【C++代码】找出字符串中第一个匹配项的下标,重复的子字符串--代码随想录

题目&#xff1a;找出字符串中第一个匹配项的下标 给你两个字符串 haystack 和 needle &#xff0c;请你在 haystack 字符串中找出 needle 字符串的第一个匹配项的下标&#xff08;下标从 0 开始&#xff09;。如果 needle 不是 haystack 的一部分&#xff0c;则返回 -1 。 题…

地理测绘基础知识(4) 照射计算上篇

我们接着上一篇来推导。 照射计算&#xff0c;是一种常用的三维几何计算。已知一个光源的光强图&#xff0c;计算光源投射到地表各处的功率密度。这种计算需求可以直观的理解为计算已知位置、指向、聚光特性的手电筒&#xff0c;计算地表某地点强度。当然&#xff0c;如果穷尽地…

mysql使用st_distance_sphere函数报错Incorrect arguments to st_distance_sphere

最近发现执行mysql st_distance_sphere报错了。 报错的信息是Incorrect arguments to st_distance_sphere。 最开始以为是跟mysql的版本有关系&#xff0c;所以看了下自己本地的mysql版本&#xff0c;执行一下sql select version(); 发现自己本地的mysql版本是 5.7.30 这…

FFmpeg报错:Connection to tcp://XXX?timeout=XXX failed: Connection timed out

一、现象 通过FFmpeg&#xff08;FFmpeg的版本是5.0.3&#xff09;拉摄像机的rtsp流获取音视频数据&#xff0c;执行命令&#xff1a; ./ffmpeg -timeout 3000000 -i "rtsp://172.16.17.156/stream/video5" 报错&#xff1a;Connection to tcp://XXX?timeoutXXX …