生成器作为(快速失败)状态机

这个想法是几周前在设计“ Generator”类时想到的,该类必须将输入发送给封装的Writer 。 实际上,它是Builder模式。 但是,规则有些复杂,用户必须以某种方式调用add...()方法,才能正确生成输出。

不用说,我不喜欢让一个BuilderImpl类在内部设置和验证各种标志,以便知道什么时候被允许的选择。 解决方案是构建一个有限状态机 ,因为构建者的界面很流畅。 像往常一样,在这篇文章中,我将通过一个例子来说明。

建造者状态机

汤姆和杰瑞(Tom&Jerry)–《老鼠麻烦》,威廉·汉纳(William Hanna)和约瑟夫·巴贝拉(Joseph Barbera)

假设我们要实现一个DateBuilder ,它将以经典的dd.mm.yyyy格式(可能还带有其他类型的分隔符,不仅. )生成一个String 。 为了简单起见,我们将只关注格式,而忽略诸如一个月中的天数,leap年之类的情况。首先是界面:

public interface DateBuilder {DateBuilder addDay(final Integer day);DateBuilder addMonth(final Integer month);DateBuilder addYear(final Integer year);DateBuilder addSeparator(final String sep);String build();}

上面的接口将有五个实现: StringDateBuilder (公共入口点), ExpectSeparatorExpectMonthExpectYearExpectBuild (这四个包均受程序包保护,对用户不可见)。 StringDataBuilder看起来像这样:

public final class StringDateBuilder implements DateBuilder {private final StringBuilder date = new StringBuilder();@Overridepublic DateBuilder addDay(final Integer day) {this.date.append(String.valueOf(day));return new ExpectSeparator(this.date);}@Overridepublic DateBuilder addMonth(final Integer month) {throw new UnsupportedOperationException("A day is expected first! Use #addDay!");}@Overridepublic DateBuilder addYear(final Integer year) {throw new UnsupportedOperationException("A day is expected first! Use #addDay!");      }@Overridepublic DateBuilder addSeparator(final String sep) {throw new UnsupportedOperationException("A day is expected first! Use #addDay!");}@Overridepublic String build() {throw new UnsupportedOperationException("Nothing to build yet! Use #addDay!");}}

我相信您已经明白了:其他四个实现将处理它们自己的情况。 例如, ExpectSeparator将从addSeparator(...)之外的所有方法中引发异常,在该方法中,它将分隔符附加到StringBuilder并返回ExpectMonth的实例。 最后,这台机器的最后一个节点将是ExpectBuild (在添加年份之后由ExpectYear返回),它将抛出build()之外所有方法的异常。

这种设计帮助我将代码对象保持较小,没有标志和if/else分支。 与往常一样,上面的每个类都易于测试,并且通过切换返回的实现,可以轻松更改构建器的行为。

当然,我不是唯一想到这些的人:先生。 尼古拉斯·弗兰克(NicolasFränkel)就在上个月在这里写下了这个想法。 但是,我觉得有必要带走我的两分钱,因为我不完全喜欢他的例子:他为构建器的节点使用了不同的接口,以保持构建器的安全性和防白痴性(例如,甚至不允许用户查看addMonthbuild方法(如果他们不应该使用的话)。 我不同意这一点,因为这意味着我需要管理更多的代码,此外,客户端将与构建者的逻辑相结合。 我宁愿只强制用户到学习如何使用生成器(它不应该是他们的一个大的努力,因为他们应该搭上一个最简单的单元测试任何异常,对不对? 吧... )

我也找到了这篇文章 ,它提供了更广泛,更理论上的解释,并不一定与Builder模式相关联-如果您考虑一下,这种方法可以用于任何必须根据其内部状态更改其行为的对象。

翻译自: https://www.javacodegeeks.com/2018/12/builder-fail-fast-state-machine.html

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

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

相关文章

【渝粤教育】电大中专市场营销管理20作业 题库

1.市场营销没有宏观市场营销和微观市场营销之分。该说法:( ) A.错误 B.正确 错误 正确答案:左边查询 学生答案:B 2.战略选择的陷阱有:盲目跟随、墨守成规、军备竞赛、多方出击、孤注一掷、本末倒置。该说法…

源码包编译安装python_Python3.7源码包编译安装-Go语言中文社区

环境:[rootlocalhost python3]# cat /etc/redhat-releaseCentOS Linux release 7.5.1804 (Core)[rootlocalhost python3]#1、下载Python方式一:方式二:进入https://www.python.org/ftp/python/ 这里存放着所有版本的Python源码。往下拉看到最…

【渝粤教育】电大中专建筑力学 (4)作业 题库

1.下列说法不正确的是()。 A.力偶在任何坐标轴上的投形恒为零 B.力可以平移到刚体内的任意一点 C.力系的合力在某一轴上的投形等于各分力在同一轴上投形的代数和 D.力使物体绕某一点转动的效应取决于力的大小和力作用线到该点的垂直距离 正确 正确答案&a…

java criteria and_criteria用法

Criteria Query通过面向对象化的设计,将数据查询条件封装为一个对象。简单来讲,Criteria Query可以看作是传统SQL的对象化表示,如:Java代码Criteria criteria session.createCriteria(User.class);criteria.add(Expression.eq(&q…

【渝粤教育】电大中专新媒体营销实务 (4)作业 题库

1.( )对新媒体的定义为:“以数字信息技术为基础,以互动传播为特点,具有创新形态的媒体。” A.新传媒产业联盟秘书长王斌 B.联合国教科文组织 C.华纳兄弟总裁施瓦茨威格 正确 正确答案:左边查询 学生答案&am…

服务网格:Istio和AWS App Mesh

本周在AWS re:Invent上的重大公告之一是AWS App Mesh 。 在谈论它之前,让我们先看一下网格到底是什么…… 什么是服务网格? 服务网格是微服务体系结构的基础结构层。 它处理服务之间的通信问题,使该通信更加可见(或“…

【渝粤教育】电大中专消费者心理学_1作业 题库

1.在西方,早期思想家也有论及消费时令和消费季节的朴素思想。该说法() A.错误 B.正确 正确 正确答案:左边查询 学生答案:A 2.体系凝构阶段大致自20世纪70年代延至20世纪末或21世纪初。该说法() …

java按键发出声音代码_怎么在java中给按钮添加声音?

可以加入GTM时间,代码如下:public class ShowCurrentTime {public static void main(String args[]){//Obtain the total milliseconds since midnight,Jan 1,1970long totalMillisecondsSystem.currentTimeMillis();//Obtain the total seconds since i…

Spring字段依赖注入示例

学习如何编写Spring Field Injection示例 。 字段注入是Spring框架 依赖注入的一种 。 在本教程中,我们将编写几个类,并看一看现场注入工程。 有关Spring依赖注入的更多信息: Spring Setter依赖注入示例 Spring构造函数依赖注入示例 Spri…

java8 新特性之流式数据处理_Java8新特性 - 集合流式编程 - 最终操作

2、数据源的获取2.1、数据源的简介数据源,顾名思义,既是流中的数据的来源。是集合的流式编程的第一步,将数据源中的数据读取到流中,进行处理。注意:将数据读取到流中进行处理的时候,与数据源中的数据没有关…

【渝粤教育】电大中专电大中专职业健康与安全考试考核试题作业 题库

试卷答案 1根据系统安全工程的观点,危险是指系统中存在导致发生不期望后果的可能性超过了( ) A极限 B人们的承受程度 C危险度 D安全系数 错误 正确答案:左边查询 学生答案:A 2对职工来说,安全是&#xff0…

java jdt_在JDT中使用Java 8 Lambda

java jdt旧 Curmudgeon 认识Smalltalk的Dude 在修改Eclipse Java开发工具 (JDT)项目正在开发的Java 8支持时,我一直在使用这种语言。 我承认我对Java 8中的lambda有点不满意。 当然,这来自于知道Smalltalk (和LISP…

java 1.8签名apk_给Android的APK程序签名和重新签名的方法

签名工具的使用Android源码编译出来的signapk.jar既可给apk签名,也可给rom签名的。使用格式:java –jar signapk.jar [-w] publickey.x509[.pem] privatekey.pk8 input.jar output.jar-w 是指对ROM签名时需使用的参数publickey.x509[.pem] 是公钥文件pri…

【渝粤教育】电大中专职业生涯规划 (3)作业 题库

1职业价值观具有明确的目的性、( )和坚定性的职业选择的态度和行为。 A自由性 B动机性 C自觉性 D制约性 错误 正确答案:左边查询 学生答案:A 2不属于探索价值观方法的是( )。 A澄清反应法 B意见表决法 C间接…

使用Oracle验证外部数据

我经常在Corda Slack频道中闲逛,并尽可能回答问题。 我尝试回答的合理数量的问题与Oracle有关。 更具体地说,何时使用一个。 我觉得我可以回答,“当您需要验证可能经常更改的外部数据时使用Oracle”。 我可能在某个时候写了一个类似的答案。 …

【渝粤教育】电大中专药理学基础 (2)_1作业 题库

1.关于苯二氮卓类镇静催眠药的叙述,不正确的是()。 A.长期应用不会产生依赖性和成瘾性 B.是目前最常用的镇静催眠药 C.可用于治疗小儿高热惊厥 D.临床上用于治疗焦虑症 E.可用于心脏电复律前给药 错误 正确答案:左边查询 学生答案…

【渝粤教育】电大中专计算机职业素养 (11)作业 题库

1.用冰山模型说明职业素养构成时,我们把浮在水面上面的知识、技能等部分称为( )的职业素养。 A.获得 B.显性 C.专业 D.隐性 错误 正确答案:左边查询 学生答案:A 2.职业素养的基本内容包括:职业道德、职业意…

java 2d 教程_Java 2D开发技巧之“灯光与阴影”

Java 2D开发技巧之“灯光与阴影”(2016-12-14 02:12:25)标签:杂谈一、 引言在本文中,我们将向你展示如何为扁平形状添加一种灯光效果以实现一种类3D外观。也许你比较满意于自己的文字表达能力,但一幅图片往往能够产生更好的效果。对于图形处理…

【渝粤教育】电大中专跨境电子商务理论与实务 (17)作业 题库

1.在按照交易主体类型中,( )面对的最终客户为企业或集团客户,提供企业、产品、服务等相关信息。 A.C2C跨境电商或平台 B.B2C跨境电商或平台 C.O2O跨境电商或平台 D.B2B跨境电商或平台 错误 正确答案:左边查询 学生答案…

jooq代码生成_将jOOQ与Spring结合使用:代码生成

jooq代码生成我们可能在本教程的第一部分中还记得jOOQ指出 jOOQ从您的数据库生成Java代码,并允许您通过其流畅的API构建类型安全SQL查询。 本教程的第一部分描述了如何配置使用jOOQ的Spring驱动的应用程序的应用程序上下文,但没有描述如何使用jOOQ创建类…