FizzBu​​zz Kata与Java流

在柔道练习仅几周之后,我的儿子感到无聊。 他抱怨说自己没有学任何东西,因为他一遍又一遍地做着同样的事情。

混淆学习和做新事物的不仅仅是幼儿。 例如,有多少软件开发人员通过执行kata或参加dojos来进行刻意练习的麻烦?

重复您已经做过很多次的练习似乎很愚蠢,但事实并非如此。 这是在您的领域成为黑带的唯一方法。 并且请记住,精通是三个内在动机之一 (其他是自主性和目的性)。

练习意味着放慢速度,将重点从结果转移到流程。 最好使用可以在有限的时间内完成的简单练习,以便可以多次执行相同的练习。

我发现我在练习时几乎总是学到新东西。 这不是因为我从上次就忘记了解决问题的方法,而是因为自那时以来我已经学到了新事物,因此可以通过新的眼光看到世界。

例如,自Java 8发布以来,我一直在尝试使用新的流类来帮助转变为更具功能性的编程风格。 这改变了我看待旧问题(例如FizzBu​​zz)的方式 。

让我们看看实际情况。 当然,我首先添加一个测试:

+ package remonsinnema.blog.fizzbuzz;
+
+ import static org.junit.Assert.assertEquals;
+
+ import org.junit.Test;
+
+
+ public class WhenFizzingAndBuzzing {
+
+   private final FizzBuzz fizzbuzz = new FizzBuzz();
+
+   @Test
+   public void shouldReplaceWithFizzAndBuzz() {
+     assertEquals(“1”, “1”, fizzbuzz.get(1));
+   }
+
+ }

该测试使用单元测试的“ 何时……应该”形式, 该形式有助于关注行为而不是实现细节。 我让Eclipse生成进行此编译所需的代码:

+ package remonsinnema.blog.fizzbuzz;
+
+
+ public class FizzBuzz {
+
+   public String get(int i) {
+     return null;
+   }
+
+ }

使测试通过的最简单的代码是伪造它 :

package remonsinnema.blog.fizzbuzz;public class FizzBuzz {public String get(int i) {
–     return null;
+     return “1”;}}

现在测试通过了,该重构了 。 我从测试中删除了重复项:

public class WhenFizzingAndBuzzing {@Testpublic void shouldReplaceWithFizzAndBuzz() {
–     assertEquals(“1”, “1”, fizzbuzz.get(1));
+     assertFizzBuzz(“1”, 1);
+   }
+
+   private void assertFizzBuzz(String expected, int n) {
+     assertEquals(Integer.toString(n), expected, fizzbuzz.get(n));}}

接下来,我添加一个测试以强制执行真正的实现:

public class WhenFizzingAndBuzzing {@Testpublic void shouldReplaceWithFizzAndBuzz() {assertFizzBuzz(“1”, 1);
+     assertFizzBuzz(“2”, 2);}private void assertFizzBuzz(String expected, int n) {package remonsinnema.blog.fizzbuzz;public class FizzBuzz {
–   public String get(int i) {
–     return “1”;
+   public String get(int n) {
+     return Integer.toString(n);}}

好的,现在让我们对Fizz进行测试:

public class WhenFizzingAndBuzzing {
public void shouldReplaceWithFizzAndBuzz() {
assertFizzBuzz(“1”, 1);
assertFizzBuzz(“2”, 2);
+ assertFizzBuzz(“Fizz”, 3);
}
private void assertFizzBuzz(String expected, int n) {
package remonsinnema.blog.fizzbuzz;
public class FizzBuzz {
public String get(int n) {
+ if (n == 3) {
+ return “Fizz”;
+ }
return Integer.toString(n);
}

Buzz类似:

public class WhenFizzingAndBuzzing {assertFizzBuzz(“Fizz”, 3);
+     assertFizzBuzz(“4”, 4);
+     assertFizzBuzz(“Buzz”, 5);}private void assertFizzBuzz(String expected, int n) {public class FizzBuzz {if (n == 3) {return “Fizz”;}
+     if (n == 5) {
+       return “Buzz”;
+     }return Integer.toString(n);}

在这里,我只是复制并粘贴了if语句以使其快速运行 。 当然,我们不应该在这里停下来,而要摆脱肮脏的东西。 在这种情况下,那是重复的。

首先,让我们更新代码以使重复更加明显:

package remonsinnema.blog.fizzbuzz;public class FizzBuzz {public String get(int n) {
–     if (n == 3) {
–       return “Fizz”;
+     MultipleReplacer replacer = new MultipleReplacer(3, “Fizz”);
+     if (n == replacer.getValue()) {
+       return replacer.getText();}
–     if (n == 5) {
–       return “Buzz”;
+     replacer = new MultipleReplacer(5, “Buzz”);
+     if (n == replacer.getValue()) {
+       return replacer.getText();}return Integer.toString(n);}
+ package remonsinnema.blog.fizzbuzz;
+
+
+ public class MultipleReplacer {
+
+   private final int value;
+   private final String text;
+
+   public MultipleReplacer(int value, String text) {
+     this.value = value;
+     this.text = text;
+   }
+
+   public int getValue() {
+     return value;
+   }
+
+   public String getText() {
+     return text;
+   }
+
+ }

我刚刚创建了一个新的值对象,以保存在复制/粘贴后必须更改的两个值。

现在,重复项更加清晰了,可以轻松删除它:

package remonsinnema.blog.fizzbuzz;
+ import java.util.Arrays;
+ import java.util.Collection;
+public class FizzBuzz {
+   private final Collection replacers = Arrays.asList(
+       new MultipleReplacer(3, “Fizz”), new MultipleReplacer(5, “Buzz”));
+public String get(int n) {
–     MultipleReplacer replacer = new MultipleReplacer(3, “Fizz”);
–     if (n == replacer.getValue()) {
–       return replacer.getText();
–     }
–     replacer = new MultipleReplacer(5, “Buzz”);
–     if (n == replacer.getValue()) {
–       return replacer.getText();
+     for (MultipleReplacer replacer : replacers) {
+       if (n == replacer.getValue()) {
+         return replacer.getText();
+       }}return Integer.toString(n);}

但是,我还没有完成清理工作。 当前代码受功能嫉妒之苦 ,我可以通过将行为移入值对象来解决:

package remonsinnema.blog.fizzbuzz;import java.util.Arrays;import java.util.Collection;
+ import java.util.Optional;public class FizzBuzz {public String get(int n) {for (MultipleReplacer replacer : replacers) {
–       if (n == replacer.getValue()) {
–         return replacer.getText();
+       Optional result = replacer.textFor(n);
+       if (result.isPresent()) {
+         return result.get();}}return Integer.toString(n);
package remonsinnema.blog.fizzbuzz;
+ import java.util.Optional;
+public class MultipleReplacer {this.text = text;}
–   public int getValue() {
–     return value;
–   }
–
–   public String getText() {
–     return text;
+   public Optional<String> textFor(int n) {
+     if (n == value) {
+       return Optional.of(text);
+     }
+     return Optional.empty();}}

现在,我已经完成了重构,我可以继续使用倍数:

public class WhenFizzingAndBuzzing {assertFizzBuzz(“Fizz”, 3);assertFizzBuzz(“4”, 4);assertFizzBuzz(“Buzz”, 5);
+     assertFizzBuzz(“Fizz”, 6);}private void assertFizzBuzz(String expected, int n) {public class MultipleReplacer {}public Optional<String> textFor(int n) {
–     if (n == value) {
+     if (n % value == 0) {return Optional.of(text);}return Optional.empty();

最终测试是同时进行“嘶嘶声”和“嗡嗡声”测试:

public class WhenFizzingAndBuzzing {assertFizzBuzz(“4”, 4);assertFizzBuzz(“Buzz”, 5);assertFizzBuzz(“Fizz”, 6);
+     assertFizzBuzz(“7”, 7);
+     assertFizzBuzz(“8”, 8);
+     assertFizzBuzz(“Fizz”, 9);
+     assertFizzBuzz(“Buzz”, 10);
+     assertFizzBuzz(“11”, 11);
+     assertFizzBuzz(“Fizz”, 12);
+     assertFizzBuzz(“13”, 13);
+     assertFizzBuzz(“14”, 14);
+     assertFizzBuzz(“FizzBuzz”, 15);}private void assertFizzBuzz(String expected, int n) {
public class FizzBuzz {public class FizzBuzz {new MultipleReplacer(3, “Fizz”), new MultipleReplacer(5, “Buzz”));public String get(int n) {
+     StringBuilder result = new StringBuilder();for (MultipleReplacer replacer : replacers) {
–       Optional<String> result = replacer.textFor(n);
–       if (result.isPresent()) {
–         return result.get();
+       Optional<String> replacement = replacer.textFor(n);
+       if (replacement.isPresent()) {
+         result.append(replacement.get());}}
+     if (result.length() > 0) {
+       return result.toString();
+     }return Integer.toString(n);}}

这段代码很复杂,但这是流可以解决的地方:

public class FizzBuzz {new MultipleReplacer(3, “Fizz”), new MultipleReplacer(5, “Buzz”));public String get(int n) {
–     StringBuilder result = new StringBuilder();
–     for (MultipleReplacer replacer : replacers) {
–       Optional<String> replacement = replacer.textFor(n);
–       if (replacement.isPresent()) {
–         result.append(replacement.get());
–       }
–     }
–     if (result.length() > 0) {
–       return result.toString();
–     }
–     return Integer.toString(n);
+     return replacers.stream()
+         .map(replacer -> replacer.textFor(n))
+         .filter(Optional::isPresent)
+         .map(optional -> optional.get())
+         .reduce((a, b) -> a + b)
+         .orElse(Integer.toString(n));}}

请注意forif语句如何消失。 而不是拼写出的东西需要如何做,我们说什么 ,我们要实现的。

我们可以应用相同的技巧来除去ode基数中剩余的if语句:

public class MultipleReplacer {}public Optional<String> textFor(int n) {
–     if (n % value == 0) {
–       return Optional.of(text);
–     }
–     return Optional.empty();
+     return Optional.of(text)
+         .filter(ignored -> n % value == 0);}}

该代码在GitHub上 。

翻译自: https://www.javacodegeeks.com/2016/05/fizzbuzz-kata-java-streams.html

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

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

相关文章

高可用架构

转载于:https://www.cnblogs.com/138026310/p/9088341.html

vc6.0快捷键

2010-09-14 17:46 F1 显示帮助,如果光标停在代码的某个字符上,显示MSDN中相应的帮助内容&#xff08;需要安装MSDN才能使用&#xff09; F2 书签功能: CtrlF2 --在某行设置一个书签(再按一次是取消) F2 --跳到下一个书签位置 ShiftF2 --跳到上一个书签位置 CtrlShiftF2 --删除…

ES6 各浏览器支持情况

http://kangax.github.io/compat-table/es6/转载于:https://www.cnblogs.com/likwin/p/9091008.html

MFC删除类的小窍门

VC 并没有提供删除一个类的简洁方法&#xff0c;我们需要手工删除&#xff0c;但过程并不复杂。例如&#xff0c;我们有一个 CMyButton 的类&#xff0c;对应的文件为 MyButton.h 和 MyButton.cpp &#xff0c;我们先到工程目录中删除这两个文件&#xff0c;此时该类信息自动从…

ios plist 国际化_Java与iOS对话:Java对象与Apple plist序列化

ios plist 国际化我很高兴地宣布我的第一个开源项目java-plist-serializer可以帮助您将Java&#xff08;尤其是基于Spring的应用程序&#xff09;与iOS应用程序集成在一起。 背景 我正在将Java webapp作为后端并且客户端是iOS设备的项目。 最近&#xff0c;我收到了创建Web服务…

vtk环境搭建(windowsXP/win7,vtk6.0.0+cmake2.8+vs2010)

1. 安装vs2010&#xff08;默认方式&#xff09; 2. 安装cmake2.8&#xff08;默认方式&#xff09; 3. 新建文件夹作为vtk文件根目录&#xff08;例如"E:\vtk6.0"&#xff09;&#xff0c;解压vtk-6.0.0.zip到根目录&#xff0c;将VTK6.0.0改名为vtk&#xff1b;解…

P1993 小K的农场 (差分约束)

题目描述 小K在MC里面建立很多很多的农场&#xff0c;总共n个&#xff0c;以至于他自己都忘记了每个农场中种植作物的具体数量了&#xff0c;他只记得一些含糊的信息&#xff08;共m个&#xff09;&#xff0c;以下列三种形式描述&#xff1a; 农场a比农场b至少多种植了c个单位…

将Quartz与Spring集成

在Java应用程序中调度作业时&#xff0c;Quartz是第一个考虑的工具。 Quartz是由最流行的RDBMS支持的作业调度程序。 这真的很方便&#xff0c;并且很容易与spring集成。 为了创建石英模式&#xff0c;您必须下载石英发行版并解压缩位于crystal-2.2.3 / docs / dbTables /中的…

linux下md5sum的使用

在linux或Unix上&#xff0c;md5sum是用来计算和校验文件报文摘要的工具程序。一般来说&#xff0c;安装了Linux后&#xff0c;就会有md5sum这个工具&#xff0c;直接在命令行终端直接运行。1、使用md5sum来产生指纹&#xff08;报文摘要&#xff09;命令如下&#xff1a;md5su…

深入理解Python中的元类(metaclass)

注&#xff1a;本文原稿来自stackoverflow&#xff0c;原文链接&#xff0c;目前已收获5k高赞。 一、类也是对象 在理解元类之前&#xff0c;你需要先掌握Python中的类。Python中类的概念借鉴于Smalltalk&#xff0c;这显得有些奇特。在大多数编程语言中&#xff0c;类就是一组…

6个步骤卸载wine

今天在ubuntu下装了个wine&#xff0c;感觉界面很难看&#xff0c;跟ubuntu风格不协调。所以我把它卸载了。 根据网上找的资料&#xff0c;我是按如下步骤卸载&#xff1a; 1.终端运行sudo apt-get remove wine&#xff0c;运行发现系统还有wine的图标残留&#xff0c;于是 2…

OpenStack基础知识-virtualenv工具详解

1、virtualenv介绍 virtualenv通过创建一个单独的虚拟化python运行环境&#xff0c;将我们所需的依赖安装进去&#xff0c;不同项目之间相互不干扰&#xff0c;从而解决不同的项目之间依赖不同&#xff0c;造成的冲突问题 2、安装virtualenv 通过pip命令&#xff0c;安装virtua…

java中的五种排序方法_用Java排序的五种有用方法

java中的五种排序方法Java排序快速概述&#xff1a; 正常的列表&#xff1a; private static List VEGETABLES Arrays.asList("apple", "cocumbers", "blackberry");Collections.sort(VEGETABLES);output: apple, blackberry, cocumbers反向排…

压缩vmware中的ubuntu系统(虚拟机瘦身大法)

压缩vmware中的ubuntu系统&#xff08;虚拟机瘦身大法&#xff09; 前提:你的虚拟机大小 < 你放置虚拟机的磁盘的剩余空间 1.在Termial(终端)里 运行"sudo vmware-toolbox"(需要root权限) 2.选择“shrink”选项卡 3.选中“/”&#xff0c;点击“shrink”按钮 4.完…

P2619 [国家集训队2]Tree I

P2619 [国家集训队2]Tree I 链接 分析&#xff1a; 为了确定白边选入的数量&#xff0c;所以给白边加一个权值&#xff0c;二分这个值&#xff0c;然后最小生成树。可以发现白边的数量虽这个值的增大而减小&#xff0c;满足单调性。 有一个问题&#xff1a;如果在二分过程中给白…

程序化JCMD访问

在线提出的问题表明&#xff0c;开发人员偶尔希望通过其Java应用程序访问通常从针对该应用程序外部运行JConsole &#xff0c; VisualVM或JDK命令行工具获得的信息类型。 以下是这类问题的一些示例&#xff1a; 如何以编程方式获取jmap直方图&#xff1f; 以编程方式从Java应…

Ubuntu瘦身与扩容运动

Ubuntu瘦身与扩容运动 2009-11-26 18:18:24| 分类&#xff1a; 计算机 | 标签&#xff1a; |字号大中小 订阅 Ubuntu瘦身与扩容运动 2009年08月14日 星期五 12:25大家都知道系统用久了就会慢慢变得臃肿,速度当然也就会有一些影响,所以当那些加速系统的方法不在奏效的时候…

认识jQuery

一、JavaScript库 把一些浏览器兼容性的代码或者需要常用的函数装在一个js文件里,封装了很多js代码的一个js文件就是一个库 二、jQuery 是一个JavaScript库&#xff0c;免费开源的&#xff0c;体积小&#xff0c;链式编程&#xff0c;隐式迭代&#xff0c;很多优点jQuery 的功能…

Axis2 WebService(配置、发布、调用)

from:http://www.lifeba.org/arch/java_axis2_webservice.html 准备工作 1、下载&#xff1a;axis2-1.5.4-bin.zip,axis2-1.5.4-war.zip 下载地址&#xff1a;http://axis.apache.org/axis2/java/core/ 2、环境变量设置 AXIS2_HOME E:\research\axis2-1.5.4-bin\axis2-1.5.4 J…

SmartPDA图片

转载于:https://www.cnblogs.com/xyyshishuaige/p/9098613.html