土城战役_避免使用FOR –反假战役

土城战役

您是否想知道FOR如何影响您的代码? 他们如何限制您的设计,更重要的是如何将您的代码转换为无人为含义的多行代码?

在这篇文章中,我们将看到如何将for的简单示例(由Francesco Cirillio提供- 反if活动)转换为更具可读性和精心设计的示例。

因此,让我们从使用FOR的原始代码开始:

public class Department {private List<Resource> resources = new ArrayList<Resource>();public void addResource(Resource resource) {this.resources.add(resource);}public void printSlips() {for (Resource resource : resources) { if(resource.lastContract().deadline().after(new Date())) { System.out.println(resource.name()); System.out.println(resource.salary());}}}}

请参见printSlips方法。 如此简单的方法,只有10条线计数白线,但却违反了最重要的规则之一,该方法在其内部混合了不同级别的抽象而不只是做一件事。

正如罗伯特·C·马丁(Robert C. Martin)在他的著作《函数应该做一件事情》中指出的那样 他们应该做得很好。 他们应该只做[…]。 如果一个函数仅执行比该函数的指定名称低一级的步骤,则该函数正在做一件事[…]。

因此,使用给定的方法外观定义,让我们回顾一下以前的方法,看看有多少事情在做
printSlips方法? 具体四个

public void printSlips() {for (Resource resource : resources) { #Cycleif(resource.lastContract().deadline().after(new Date())) { #Selection#Media System.out.println(resource.name()); #ContentSystem.out.println(resource.salary());}}}

该方法是循环,选择资源,访问内容以及访问媒体。 看到它们每个都属于不同的抽象级别,打印到控制台应该以不同的级别检查资源是否尚未到期。

让我们看看Francesco提出的解决方案。

首先要做的是将主要功能分成三个类和两个接口,一个用于迭代资源,另一个用于选择尚未过期的资源,另一个用于打印资源。 通过这种方法,我们正在创建一个旨在扩展的解决方案,并且还提高了可读性。

现在是时候编写代码了:

如果资源满足已实现条件,则将使用谓词接口来实现。

public interface Predicate {boolean is(Resource each);}

例如,在我们的例子中,接口的实现如下所示:

public class InForcePredicate implements Predicate {public boolean is(Resource each) {return each.lastContract().deadline().after(new Date());}}

我们将条件转移到InForcePredicate类。 请注意,如果我们要创建一个检查合同是否过期的类,我们将创建一个实现Predicate的新类,其内容类似于return each.lastContract()。deadline()。before(new Date())

下一个接口是Block接口,它将实现对媒体的访问。 在这种情况下,要进行控制台:

public interface Block {void evaluate(Resource resource);}

及其实现:

public class PrintSlip implements Block {public void evaluate(Resource resource) {System.out.println(resource.name()); System.out.println(resource.salary());}}

再次注意,更改信息的发送位置(控制台,文件,网络等)仅是实现Block接口的问题。

最后一类是包含资源迭代器的类,还提供了调用先前创建的每个接口的方法:

public class ResourceOrderedCollection {private Collection<Resource> resources = new ArrayList<Resource>();public ResourceOrderedCollection() {super();}public ResourceOrderedCollection(Collection<Resource> resources) {this.resources = resources;}public void add(Resource resource) {this.resources.add(resource);}public void forEachDo(Block block) {Iterator<Resource> iterator = resources.iterator();while(iterator.hasNext()) {block.evaluate(iterator.next());}}public ResourceOrderedCollection select(Predicate predicate) {ResourceOrderedCollection resourceOrderedCollection = new ResourceOrderedCollection();Iterator<Resource> iterator = resources.iterator();while(iterator.hasNext()) {Resource resource = iterator.next();if(predicate.is(resource)) {resourceOrderedCollection.add(resource);}}return resourceOrderedCollection;}}

请参阅接下来的三个要点:

  • 第一个是构造函数接收资源列表。
  • 第二个是select方法接收一个谓词,该谓词将执行到迭代器中,以知道是否可以选择打印资源。 最后,返回带有资源且没有过期合同的ResourceOrderedCollection的新实例。
  • 第三个forEachDo方法接收一个Block接口,该接口由资源列表的每个元素调用。

最后使用以前开发的类修改了Department类:

public class Department {private List<Resource> resources = new ArrayList<Resource>();public void addResource(Resource resource) {this.resources.add(resource);}public void printSlips() {new ResourceOrderedCollection(this.resources).select(new InForcePredicate()).forEachDo(new PrintSlip());}}

注意,现在printSlips方法包含具有相同抽象级别的单个可读行。

请注意,类名和接口名取自Francesco的示例,但是如果我也要这样做,则将选择更多的代表性名称。 Cirillo的方法不错,但需要考虑一些小方面。 例如,它具有“ 垂直问题 ”: Predicate接口中的InForcePredicate实例使用五行源代码来封装单个语句。

我们探索了问题的两种可能解决方案,这是Cirillio提出的最后一种解决方案。 对于此问题,还有许多其他可能且正确的解决方案,例如,使用“ 模板方法模式” ,或混合使用Lambdaj和(或不使用) 闭包( Lambdaj语法可能会有些混乱)。 它们都有优点和缺点,但是它们都使您的代码更具可读性,而且更重要,所有功能都只能做一件事,它们只能做得很好。

作为本文的最后注解, JDK 8将提供对本机关闭的支持,还将提供Lambdaj现在提供的许多功能。 同时, JDK 8不稳定(计划于2013年中半决赛)或您的旧代码(从JDK 8的角度来看) 不稳定Lambdaj确实是一个很好的旅行者。

我们不断学习。

参考: 避免FOR –来自我们的JCG合作伙伴 Alex Soto的“ 反若战役”,来自One Jar to Rule All All博客。

翻译自: https://www.javacodegeeks.com/2012/11/avoiding-fors-anti-if-campaign.html

土城战役

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

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

相关文章

Map以自定义类做为键值

map在STL中的定义 template <class Key, class T, class Compare less<Key>, class Alloc alloc> 第一个参数Key是关键字类型 第二个参数T是值类型 第三个参数Compare是比较函数&#xff08;仿函数&#xff09; 第四个参数是内存配置对象 map内部存储机制实际是以…

“基于深度学习的目标检测跟工业机器人结合”实现过程

基于深度学习的目标检测技术在工业机器人中的应用&#xff0c;可以帮助机器人实现自动化的目标检测和识别任务。以下是基于深度学习的目标检测与工业机器人结合的一般实现过程&#xff1a; 1. 数据采集和准备&#xff1a; 首先&#xff0c;收集和准备用于训练深度学习模型的数据…

小规模流处理kata。 第2部分:RxJava 1.x / 2.x

在第1部分&#xff1a;线程池中&#xff0c;我们设计并实现了相对简单的系统&#xff0c;用于实时处理事件。 确保您已阅读上一部分&#xff0c;因为它包含一些我们将重用的类。 以防万一这是要求&#xff1a; 一个系统每秒传送约一千个事件。 每个Event至少具有两个属性&…

java 计算信度,11.5.2 评分者信度实例分析

11.5.2 评分者信度实例分析【例11.5】 某校学生举办歌唱大赛&#xff0c;请5位评委老师为最终进入决赛的6名同学评定等级&#xff0c;结果如表11-10所示&#xff0c;请计算其信度。表11-10 歌唱大赛评定等级结果学生教师A1A2A3A4A5A6A344335B434343C233253D445344E324333解&a…

JAVA 类加载 随记

视频: https://www.bilibili.com/video/av29502877 1 JVM把Class加载到内存当中&#xff0c;检验解析初始化。默认使用的懒加载方式。 以下步骤是并行执行 可以把加载源看成JAVA配置文件。 解析&#xff1a; 符号引用&#xff1a; 类名&#xff0c;基本类型 直接引用&#xff…

Linux IO实时监控iostat命令详解

简介 iostat主要用于监控系统设备的IO负载情况&#xff0c;iostat首次运行时显示自系统启动开始的各项统计信息&#xff0c;之后运行iostat将显示自上次运行该命令以后的统计信息。用户可以通过指定统计的次数和时间来获得所需的统计信息。 语法 iostat [ -c ] [ -d ] [ -h ] […

打破冷漠僵局文章_研究僵局–第2部分

打破冷漠僵局文章调查死锁时最重要的要求之一就是要研究死锁。 在我的上一个博客中&#xff0c;我写了一些名为DeadlockDemo代码&#xff0c;该代码使用一堆线程在一系列银行账户之间转移随机数&#xff0c;然后陷入僵局。 该博客运行该代码以演示获取线程转储的几种方法。 线…

七牛云php20m文件上传不了,七牛云存储 - 用php上传图片,我在本地测试,用php 接口,不成功...

七牛反馈显示信息说明已经成功了&#xff0c;但是在七牛空间显示的文件却不完整请问这是为什么啊&#xff1f;&#xff01;&#xff01;测试文件如下&#xff0c;本地localhost测试&#xff1a;require_once("qiniu/io.php");require_once("qiniu/rs.php")…

洛谷 P2463 [SDOI2008]Sandy的卡片 解题报告

P2463 [SDOI2008]Sandy的卡片 题意 给\(n(\le 1000)\)串&#xff0c;定义两个串相等为“长度相同&#xff0c;且一个串每个数加某个数与另一个串完全相同”&#xff0c;求所有串的最长公共子串&#xff0c;每个串长\(\le 101\)&#xff0c;值域\(\in [0,1864]\) 先差分一下&…

linux和windows的进程的虚拟地址空间

昨晚看到了深夜&#xff0c;终于对进程的虚拟地址空间有了个大致的了解&#xff0c;很激动&#xff0c;也很欣慰。回头想来&#xff0c;一个程序员&#xff0c;真的应该知道这些知识&#xff0c;否则还真不太称职。 首先告诉大家&#xff0c;我后面提到的这些知识在《windows核…

安装Red Hat Container Development Kit 2.2版本

当应用程序开发人员或架构师负责探索容器化应用程序提供的可能性时&#xff0c;没有比Red Hat容器开发套件&#xff08;CDK&#xff09;容易的了。 Red Hat CDK具有本地OSX&#xff0c;Linux或Windows环境所需的所有Cloud工具&#xff0c;并且已预先配置了一些容器供您浏览。 …

php_sapi常量,PHP常量PHP_SAPI与函数php_sapi_name()简介,PHP运行环境检测

php_sapi_name() 是用来检测PHP运行环境的函数。该函数返回一个描述PHP与WEB服务器接口的小写字符串。例如&#xff1a;aolserver,apache,apache2filter,apache2handler,caudium,cgi(until PHP 5.3),cgi-fcgi,cli,continuity,embed,isapi,litespeed,milter,nsapi,phttpd,pi3web…

怎么学习正则表达式?(正则的使用心得)

以前使用正则是不会自己去学或者去了解怎么实现正则的语法的&#xff0c;感觉好难懂的样子&#xff0c;于是拖到现在 其实正则不是我想象中的那么难&#xff0c;至少入门还是比较简单。我刚学习了一些比较简单的&#xff0c;谈谈我对正则的理解以及使用心得&#xff0c;希望能帮…

java+解析占位符,如何告诉Spring使用Java映射来解析属性占位符?

Spring提供了一个MapPropertySource,您可以在ApplicationContext的环境中注册(您需要一个大多数ApplicationContext实现提供的ConfigurableEnvironment).解析器(按顺序)使用这些已注册的PropertySource值来查找占位符名称的值.这是一个完整的例子&#xff1a;ConfigurationComp…

UOJ207 共价大爷游长沙

考虑到路径是有向的&#xff0c;不是很好维护。 如果路径无向的话&#xff0c;可以直接转化为链加和查询操作。 既然有向的话&#xff0c;不妨考虑一波hash。 对于一组询问x,y&#xff0c;可以把树划分为两颗子树。 合法显然需要满足 x子树的起点的hashy子树的终点的hash x子树…

mysql select null 0,查询值中为NULL,在MySQL中产生0.00

我有一个动态编写的查询(通过Joomla的OO PHP)将一些值插入MySQL数据库.用户填写的表单上有一个字段用于金额,如果它们留空,我希望进入系统的值为NULL.我已经将错误日志中的查询写出来了;这是查询的样子&#xff1a;INSERT INTO arrc_Voucher(VoucherNbr,securityCode,sequentia…

oracle adf_Oracle ADF移动世界! 你好!

oracle adf您好&#xff0c;ADF Mobile&#xff0c;世界&#xff01; 您可能已经知道... ADF Mobile在这里&#xff01; 以下是一些链接&#xff0c;这些链接会让您有宾至如归的感觉。 ADF Mobile主页&#xff1a; http://www.oracle.com/technetwork/developer-tools/adf/o…

线段树||BZOJ1593: [Usaco2008 Feb]Hotel 旅馆||Luogu P2894 [USACO08FEB]酒店Hotel

题面&#xff1a;P2894 [USACO08FEB]酒店Hotel 题解&#xff1a;和基础的线段树操作差别不是很大&#xff0c;就是在传统的线段树基础上多维护一段区间最长的合法前驱&#xff08;h_&#xff09;&#xff0c;最长合法后驱&#xff08;t_&#xff09;&#xff0c;一段中最长的合…

Linux内存管理详解

前一段时间看了《深入理解Linux内核》对其中的内存管理部分花了不少时间&#xff0c;但是还是有很多问题不是很清楚&#xff0c;最近又花了一些时间复习了一下&#xff0c;在这里记录下自己的理解和对Linux中内存管理的一些看法和认识。 我比较喜欢搞清楚一个技术本身的发展历程…

JavaOne 2016 Essentials:7个您不容错过的事件和会话

参加JavaOne吗&#xff1f; 确保您不会错过这些活动 又到了每年的这个时候。 旧金山一年一度的Java假期即将来临&#xff0c;全市发生了超过400场会议和活动。 由于所有这些内容和新体验都一次发生&#xff0c;因此很容易就无法跟踪正在发生的事情。 在这篇文章中&#xff0c…