当前位置: 首页 > news >正文

免费视频网站制作/手机百度下载免费

免费视频网站制作,手机百度下载免费,wordpress 模板 破解版,赌博网站建设静态工厂和构造器有个共同的局限性:它们都不能很好地扩展到大量的可选参数。比如用一个类表示包装食品外面显示的营养成分标签。这些标签中有几个域是必需的:每份的含量、每罐的含量以及每份的卡路里。还有超过20个的可选域:总脂肪量、饱和脂…

静态工厂和构造器有个共同的局限性:它们都不能很好地扩展到大量的可选参数。比如用一个类表示包装食品外面显示的营养成分标签。这些标签中有几个域是必需的:每份的含量、每罐的含量以及每份的卡路里。还有超过20个的可选域:总脂肪量、饱和脂肪量、转化脂肪、胆固醇、钠等等。大多数产品在某几个可选域中都会有非零的值。 

对于这样的类,应该用哪种构造器或者静态工厂来编写呢?程序员一向习惯采用重叠构造器模式,在这种模式下,提供的第一个构造器只有必要的参数,第二个构造器有一个可选参数,第三个构造器有两个可选参数,以此类推,最后一个构造器包含所有可选的参数。下面有个示例,为了简单起见,它只显示四个可选域:

final修饰的变量表示赋值之后不能再进行更改,系统赋默认值也算赋值,因此系统也不会赋默认值

/*** 营养成分*/
public class NutritionFacts {private final int servingSize; //  每份含量             requiredprivate final int servings; //    每罐含量     requiredprivate final int calories;// 卡路里/罐      optionalprivate final int fat;//   脂肪/罐              optionalprivate final int sodium; //   钠/罐         optionalprivate final int carbohydrate; // 碳水/罐     optionalpublic NutritionFacts(int servingSize, int servings) {this(servingSize, servings, 0);}public NutritionFacts(int servingSize, int servings, int calories) {this(servingSize, servings, calories, 0);}public NutritionFacts(int servingSize, int servings, int calories, int fat) {this(servingSize, servings, calories, fat, 0);}public NutritionFacts(int servingSize, int servings, int calories, int fat, int sodium) {this(servingSize, servings, calories, fat, sodium, 0);}public NutritionFacts(int servingSize, int servings, int calories, int fat, int sodium, int carbohydrate) {this.servingSize = servingSize;this.servings = servings;this.calories = calories;this.fat = fat;this.sodium = sodium;this.carbohydrate = carbohydrate;}
} 

当你想要创建实例的时候,就利用参数列表最短的构造器,该列表中包含了要设置的所有参数: 

NutritionFacts cocaCola = new NutritionFacts(240 ,8,100,0,35,27); 

这个构造器调用通常需要许多你本不想设置的参数,但还是不得不为它们传递值。在这个例子中,我们给fat 传递了一个值为0 。 如果“仅仅”是这6个参数,看起来还不算太糟糕,问题是随着参数数目的增加,它很快就失去了控制。

简而言之,重叠构造器模式可行,但是当有很多参数的时候,客户端代码会很难编写,并且仍然很难阅读。如果读者想知道那些值是什么意思,必须很仔细地数着这些参数来探个究竟。一长串类型相同的参数会导致一些微妙的错误。如果客户端不小心颠倒了其中两个参数的顺序,编译器也不会出错,但是程序在运行时会出现错误的行为

遇到许多可选的构造器参数的时候,还有第二种代替办法,即JavaBeans模式,在这种模式下,取消掉final修饰符,先调用一个无参构造器来创建对象,然后再调用setter 方法来设置每个必要的参数,以及每个相关的可选参数

/*** 营养成分*/
public class NutritionFacts {private  int servingSize; //  每份含量             requiredprivate  int servings; //    每罐含量     requiredprivate  int calories;// 卡路里/罐      optionalprivate  int fat;//   脂肪/罐              optionalprivate  int sodium; //   钠/罐         optionalprivate  int carbohydrate; // 碳水/罐     optionalpublic int getServingSize() {return servingSize;}public void setServingSize(int servingSize) {this.servingSize = servingSize;}public int getServings() {return servings;}public void setServings(int servings) {this.servings = servings;}public int getCalories() {return calories;}public void setCalories(int calories) {this.calories = calories;}public int getFat() {return fat;}public void setFat(int fat) {this.fat = fat;}public int getSodium() {return sodium;}public void setSodium(int sodium) {this.sodium = sodium;}public int getCarbohydrate() {return carbohydrate;}public void setCarbohydrate(int carbohydrate) {this.carbohydrate = carbohydrate;}
}

这种模式弥补了重叠构造器模式的不足。说得明白一点,就是创建实例很容易,这样产生的代码读起来也很容易:

NutritionFacts cocaCola = new NutritionFacts();
cocaCola.setServingSize(240);
cocaCola.setServings(8);
cocaCola.setCalories(100);
cocaCola.setSodium(35);
cocaCola.setCarbohydrate(27);

遗憾的是,JavaBeans 模式自身有着很严重的缺点。因为构造过程被分到了几个调用中, 在构造过程中,JavaBeans 可能处于不一致的状态。类无法仅仅通过检验构造器参数的有效性来保证一致性。试图使用处于不一致状态的对象将会导致失败,这种失败与包含错误的代码大相径庭,因此调试起来十分困难。与此相关的另一点不足在于,JavaBeans 模式使得把类做成不可变的可能性不复存在,这就需要程序员付出额外的努力来确保它的线程安全。

幸运的是,还有第三种替代方法,它既能保证像重叠构造器模式那样的安全性,也能保证像JavaBeans 那么好的可读性。这就是建造者(Builder)模式的一种形式,它不直接生成想要的对象,而是让客户端利用所有必要的参数调用构造器(或者静态工厂),得到一个builder 对象。然后客户端在builder 对象上调用类似于setter 的方法,来设置每个相关的可选参数。最后,客户端调用无参的build 方法来生成通常是不可变的对象。这个builder 通常是它构建的类的静态成员类,下面就是它的示例:

/*** 营养成分*/
public class NutritionFacts {private final int servingSize; //  每份含量             requiredprivate final int servings; //    每罐含量     requiredprivate final int calories;// 卡路里/罐      optionalprivate final int fat;//   脂肪/罐              optionalprivate final int sodium; //   钠/罐         optionalprivate final int carbohydrate; // 碳水/罐     optionalprivate NutritionFacts(Builder builder) {servingSize = builder.servingSize;servings = builder.servings;calories = builder.calories;fat = builder.fat;sodium= builder.sodium;carbohydrate = builder.carbohydrate;} public static class Builder{private int servingSize; // (ml) 每份含量             requiredprivate int servings; // (per container) 每罐含量     requiredprivate int calories;// (per serving) 卡路里/每罐      optionalprivate int fat;// (g/serving)脂肪  g/罐              optionalprivate int sodium; // (mg/serving) 钠  mg/罐         optionalprivate int carbohydrate; //(g/serving) 碳水 g/罐     optionalpublic Builder(int servingSize,int servings){this.servingSize = servingSize;this.servings = servings;}public Builder calories(int val){calories = val;return this;}public Builder fat(int val){fat = val;return this;}public Builder sodium(int val){sodium = val;return this;}public Builder carbohydrate(int val){carbohydrate = val;return this;}public NutritionFacts build(){return new NutritionFacts(this);}}
}

注意 NutritionFacts 是不可变的,所有的默认参数值都单独放在一个地方。builder的设置方法返回自身,以便把调用链接起来,得到一个流式API。下面就是其客户端代码:

NutritionFacts cocaCola = new NutritionFacts.Builder(240,8).calories(100).sodium(35).carbohydrate(27).build(); 

这样的客户端代码很容易编写,更为重要的是易于阅读。Builder 模式模拟了可选参数

为了简洁起见,示例中省略了有效性检查。要想尽快侦测到无效的参数,可以在builder 的构造器和方法中检查参数的有效性。查看不可变量,包括build方法调用的构造器中的多个参数。为了确保这些不变量免受攻击,从builder 复制完参数之后,要检查对象域(详见第50条)。如果检查失败就抛出 IllegalArgumentException,其中的详细信息会说明哪些参数是无效的。

与构造器相比,builder 的微弱优势在于,它可以有多个可变(varargs)参数。因为builder 是利用单独的方法来设置每一个参数。

Builder 模式的确也有它自身的不足。为了创建对象,必须先创建它的构建器。虽然创建这个构建器的开销在实践中可能不那么明显,但是在某些十分注重性能的情况下,可能就成问题了。Builder 模式还比重叠构造器模式更加冗长,因此它只在有很多参数的时候才使用,比如4个或更多。但是记住,将来你可能需要添加参数。如果一开始就使用构造器或静态工厂,等到类需要多个参数时才添加构造器,就会无法控制,那些过时的构造器或者静态工厂显得十分不协调。因此,通常最好一开始就使用构建器(Builder)。

简而言之,如果类的构造器或者静态工厂中具有多个参数,设计这种类时,Builder模式就是一种不错的选择,特别是当大多数参数都是可选或者类型相同的时候。与使用重叠构造器模式相比,使用Builder 模式的客户端将更易于阅读和编写,构建器也比JavaBeans 更加安全


如果是内部调用较多,确定没有安全问题,JavaBean模式和builder 已经非常接近了,并且,可以使用链式调用的方式,让JavaBean 的调用显得更简洁,更像builder 

/*** 营养成分*/
public class NutritionFacts {private int servingSize; //  每份含量             requiredprivate int servings; //    每罐含量     requiredprivate int calories;// 卡路里/罐      optionalprivate int fat;//   脂肪/罐              optionalprivate int sodium; //   钠/罐         optionalprivate int carbohydrate; // 碳水/罐     optionalpublic NutritionFacts setServingSize(int servingSize) {this.servingSize = servingSize;return this;}public NutritionFacts setServings(int servings) {this.servings = servings;return this;}public NutritionFacts setCalories(int calories) {this.calories = calories;return this;}public NutritionFacts setFat(int fat) {this.fat = fat;return this;}public NutritionFacts setSodium(int sodium) {this.sodium = sodium;return this;}public NutritionFacts setCarbohydrate(int carbohydrate) {this.carbohydrate = carbohydrate;return this;}public static void main(String[] args) {NutritionFacts cocaCola = new NutritionFacts().setServingSize(240).setServings(8).setCalories(100).setSodium(35).setCarbohydrate(27);} 
}

当然,现在很多公司和团队已经开始积极使用Lombok 来简化bean 对象。可以如下

/*** 营养成分*/
@Getter
@Setter
@Accessors(chain = true)
public class NutritionFacts {private int servingSize; //  每份含量             requiredprivate int servings; //    每罐含量     requiredprivate int calories;// 卡路里/罐      optionalprivate int fat;//   脂肪/罐              optionalprivate int sodium; //   钠/罐         optionalprivate int carbohydrate; // 碳水/罐     optionalpublic static void main(String[] args) {NutritionFacts cocaCola = new NutritionFacts().setServingSize(240).setServings(8).setCalories(100).setSodium(35).setCarbohydrate(27);}
}

相关文章:

创建和销毁对象——遇到多个构造器参数时要考虑使用构建器

静态工厂和构造器有个共同的局限性:它们都不能很好地扩展到大量的可选参数。比如用一个类表示包装食品外面显示的营养成分标签。这些标签中有几个域是必需的:每份的含量、每罐的含量以及每份的卡路里。还有超过20个的可选域:总脂肪量、饱和脂…...

【c++学习】入门c++(中)

目录一. 前言二. 函数重载1. 概念2.函数名修饰规则三 .引用(&)1. 概念2. 引用特性3.应用1.做参数2. 做返回值3. 传值、传引用效率比较4.引用和指针的区别四 . 结语一. 前言 小伙伴们大家好,今天我们继续学习c入门知识,今天的…...

论文阅读_AlphaGo_Zero

论文信息 name_en: Mastering the game of Go without human knowledge name_ch: 在没有人类知识的情况下掌握围棋游戏 paper_addr: http://www.nature.com/articles/nature24270 doi: 10.1038/nature24270 date_publish: 2017-10-01 tags: [‘深度学习’,‘强化学习’] if: 6…...

一文教你用Python创建自己的装饰器

python装饰器在平常的python编程中用到的还是很多的,在本篇文章中我们先来介绍一下python中最常使用的staticmethod装饰器的使用。 目录一、staticmethod二、自定义装饰器python类实现装饰器python函数嵌套实现装饰器多个装饰器调用三、带参数的装饰器一、staticmet…...

华为OD机试 - 任务总执行时长(JS)

任务总执行时长 题目 任务编排服务负责对任务进行组合调度。参与编排的任务又两种类型,其中一种执行时长为taskA,另一种执行时长为taskB。任务一旦开始执行不能被打断,且任务可连续执行。服务每次可以编排num个任务。 请编写一个方法,生成每次编排后的任务所有可能的总执…...

pytorch离线快速安装

1.pytorch官网查看cuda版本对应的torch和torchvisionde 版本(ncvv -V,nvidia-sim查看cuda对应的版本) 2.离线下载对应版本,网址https://download.pytorch.org/whl/torch_stable.html 我下载的: cu113/torch-1.12.0%2Bcu113-cp37-cp37m-win_…...

华为OD机试 - 数组合并(JS)

数组合并 题目 现在有多组整数数组,需要将他们合并成一个新的数组。 合并规则,从每个数组里按顺序取出固定长度的内容合并到新的数组中, 取完的内容会删除掉, 如果该行不足固定长度或者已经为空, 则直接取出剩余部分的内容放到新的数组中,继续下一行。 如样例1,获得长度3,先遍…...

不要让GPT成为你通向“学业作弊”的捷径——使用GPT检测工具来帮助你保持正确的方向

不要让GPT成为你通向“学业作弊”的捷径——使用GPT检测工具来帮助你保持正确的方向 最近,多所美国高校以及香港大学等都明确禁止在校使用ChatGPT等智能文本生成工具。GPT(Generative Pre-trained Transformer)是一种自然语言处理技术&#x…...

基于matlab的斜视模式下SAR建模

一、前言此示例说明如何使用线性 FM (LFM) 波形对基于聚光灯的合成孔径雷达 (SAR) 系统进行建模。在斜视模式下,SAR平台根据需要从宽侧斜视一定角度向前或向后看。斜视模式有助于对位于当前雷达平台位置前面的区域进行…...

15-基础加强-1-类加载器反射

文章目录1.类加载器1.1类加载器【理解】1.2类加载的过程【理解】1.3类加载的分类【理解】1.4双亲委派模型【理解】1.5ClassLoader 中的两个方法【应用】2.反射2.1反射的概述【理解】2.2获取Class类对象的三种方式【应用】 第1步:获取类的Class对象2.3反射获取构造方…...

基于SSM,Spring, BootStrap 毕业设计管理系统的设计与实现

目录 一.前言介绍 二、主要技术 2.1 SSM框架介绍 2.2 MYSQL数据库 2.3 持久层框架MyBatis 2.4 前端框架BootStrap 三. 系统设计 3.1 系统架构设计 3.2 系统功能模块 3.2.1 学生模块 3.2.2 教师模块 3.2.3 管理员模块 四、数据库设计 4.1 数据分析 4.2 概念设计 …...

一招鉴别真假ChatGPT,并简要介绍ChatGPT、GPT、GPT2和GPT3模型之间的区别和联系

以下内容除红色字体部分之外,其他均来源于ChatGPT自动撰写。 ChatGPT是基于GPT模型的对话生成模型,旨在通过对话模拟实现自然语言交互。它是为了改善人机对话体验而设计的,主要应用于聊天机器人、智能客服等场景。 与GPT模型相比,…...

华为OD机试 - 特异性双端队列(JS)

特异性双端队列 题目 有一个特异性的双端队列,该队列可以从头部到尾部添加数据,但是只能从头部移除数据。 小A一次执行 2n 个指令往队列中添加数据和移除数据, 其中 n 个指令是添加数据(可能从头部也可以从尾部添加) 依次添加 1 到 n , n 个指令是移出数据 现在要求移除数…...

Nginx自动封禁可疑Ip

文章目录一、Nginx封禁ip1、简介2、nignx 禁止IP访问2.1 方法一2.2 方法二3、关于 deny 的使用二、脚本自动封禁Ip1、流程介绍2、脚本实战2.1 核心脚本解释2.2 编写shell脚本2.3 crontab定时一、Nginx封禁ip 1、简介 在网站维护过程中,有时候我们需要对一些IP地址…...

分布式事务--理论基础

1、事务基础 1.1、什么是事务 事务可以看做是一次大的活动,它由不同的小活动组成,这些活动要么全部成功,要么全部失败。 1.2、本地事务 在同一个进程内,控制同一数据源的事务,称为本地事务。例如数据库事务。 在计…...

Matlab数学建模常用算法及论文插图绘制模板资源合集

最近有很多朋友咨询我关于Matlab论文插图绘制方面的问题。 问了一下,这些朋友中,除了写博士论文的,大部分都是要参加美赛的。 这让我突然想起,自己曾经为了水论文,购买过一批Matlab数学建模的资料。 想了想&#xf…...

C语言【动态内存管理 后篇】

动态内存管理 后篇🫅经典例题🤦‍♂️题目1🤦‍♂️题目2🤦‍♂️题目3🤦‍♂️题目4🫅C/C程序的内存开辟前面的一篇文章动态内存管理 前篇,我们已经了解过了动态内存管理的相关信息&#xff0c…...

四大步骤,教你彻底关闭Win10自动更新

文章目录一、禁用Windows Update服务二、在组策略里关闭Win10自动更新相关服务三、禁用任务计划里边的Win10自动更新四、在注册表中关闭Win10自动更新参考资料一、禁用Windows Update服务 1、同时按下键盘 Win R,打开运行对话框,然后输入命令 services…...

通信算法之一百零四:QPSK完整收发仿真链路

1.发射机物理层基带仿真链路 1.1 % Generates the data to be transmitted [transmittedBin, ~] BitGenerator(); 2.2 % Modulates the bits into QPSK symbols modulatedData QPSKModulator(transmittedBin); 2.3 % Square root Raised Cosine Transmit Filter %comm…...

时间复杂度(超详解+例题)

全文目录引言如何衡量一个算法的好坏时间复杂度时间复杂度的定义时间复杂度的大O表示法实例test1test2test3test4test5总结引言 如何衡量一个算法的好坏 我们在写算法的时候,对于实现同样的作用的不同算法,我们如何判断这个算法的好坏呢? …...

【Java面试总结】Maven篇

【Java面试总结】Maven篇1.Maven坐标是啥2.Maven常见的依赖范围有哪些?3.多模块如何聚合4.对于一个多模块项目,如果管理项目依赖的版本5.maven怎么解决版本冲突6.Maven常用命令有哪些?1.Maven坐标是啥 一般maven使用groupID,artifactId&…...

【每日一题Day123】LC1792最大平均通过率 | 堆

最大平均通过率【LC1792】 一所学校里有一些班级,每个班级里有一些学生,现在每个班都会进行一场期末考试。给你一个二维数组 classes ,其中 classes[i] [passi, totali] ,表示你提前知道了第 i 个班级总共有 totali 个学生&#…...

[安装之5] Mac pro更换大内存固态硬盘实践教程

近由于mac电脑内存吃紧,安装大的软件,是不是要提示一下内存不够,内心非常的不爽。作为一款A1502版的mac,128G固态硬盘通常被称为“乞丐版”。提前做好准备工作后,我周末花了一天的时间搞定这件事,为了能够帮…...

04 Python变量的声明与使用

基本上,在所有的计算机编程语言中,都会用到变量,变量将数据存储在计算机内存中。 变量是指存储数据的内存地址,通过变量名,我们可以找到这个变量名对应的内容。 命名变量时不允许使用数字、特殊字符、连字符开头。 变量可以有一个短名称(如 x、y、z),但强烈建议使用更具…...

LeetCode 2418. 按身高排序

给你一个字符串数组 names ,和一个由 互不相同 的正整数组成的数组 heights 。两个数组的长度均为 n 。 对于每个下标 i,names[i] 和 heights[i] 表示第 i 个人的名字和身高。 请按身高 降序 顺序返回对应的名字数组 names 。 示例 1: 输…...

一文了解Hotspot虚拟机下JAVA对象从创建到回收的生命周期

Java虚拟机是Java的核心和基础,他是Java编译器和操作系统平台之间处理器,能实现跨平台运行Java程序。本文主要讲解的是虚拟机如何管理对象,即Java对象在JVM虚拟机中被创建到回收的流程 Java对象从创建到回收的生命周期对象创建流程1.类加载检…...

【Java基础】Java对象创建的几种方式

先上关键内容,所用到的代码请参考文末示例代码。一、使用new关键字创建对象这是一种最常用的创建对象的方式。Student student1 new Student();二、使用Class的newInstance()方法创建对象需要有一个无参构造方法,这个newInstance()方法调用无参的构造函…...

社保缴费满15年就可以不缴了?6个很多人最关心的问题权威解答来了

一、社保缴费满15年就可以不缴了? 上海市政府新闻办公室2022年在微信号发文表示,社会保险是由国家通过立法强制建立的社会保障制度,用人单位和劳动者都必须依法参加社会保险。即使职工与用人单位商议签订了不参加社保的所谓“协议”&#xf…...

关于HDFS

目录 一、HDFS概述 二、HDFS架构与工作机制 三、HDFS的Shell操作 四、Hdfs的API操作 一、HDFS概述 HDFS:Hadoop Distributed File System;一种分布式文件管理系统,通过目录树定位文件。使用场景:一次写入,多次读出…...

C++入门:类 对象

C 在 C 语言的基础上增加了面向对象编程,C 支持面向对象程序设计。类是 C 的核心特性,通常被称为用户定义的类型。类用于指定对象的形式,它包含了数据表示法和用于处理数据的方法。类中的数据和方法称为类的成员。函数在一个类中被称为类的成…...