商务网站专题页,昆明网站建设方案策划,建设网站改版,南宁太阳能网站建设您是否想知道FOR如何影响您的代码#xff1f; 他们如何限制您的设计#xff0c;更重要的是如何将您的代码转换为无人为含义的多行代码#xff1f; 在这篇文章中#xff0c;我们将看到如何将for的简单示例#xff08;由Francesco Cirillio提供- 反if活动#xff09;转换为… 您是否想知道FOR如何影响您的代码 他们如何限制您的设计更重要的是如何将您的代码转换为无人为含义的多行代码 在这篇文章中我们将看到如何将for的简单示例由Francesco Cirillio提供- 反if活动转换为更具可读性和精心设计的示例。 因此让我们从使用FOR的原始代码开始 public class Department {private ListResource resources new ArrayListResource();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。beforenew 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 CollectionResource resources new ArrayListResource();public ResourceOrderedCollection() {super();}public ResourceOrderedCollection(CollectionResource resources) {this.resources resources;}public void add(Resource resource) {this.resources.add(resource);}public void forEachDo(Block block) {IteratorResource iterator resources.iterator();while(iterator.hasNext()) {block.evaluate(iterator.next());}}public ResourceOrderedCollection select(Predicate predicate) {ResourceOrderedCollection resourceOrderedCollection new ResourceOrderedCollection();IteratorResource 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 ListResource resources new ArrayListResource();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确实是一个很好的同伴。 我们不断学习。 参考 避免FORs –我们的JCG合作伙伴 Alex Soto的“ 反若战役”来自“ One Jar to Rule Allm All”博客。 翻译自: https://www.javacodegeeks.com/2012/11/avoiding-fors-anti-if-campaign.html