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

混淆学习和做新事物的不仅仅是幼儿。 例如,有多少软件开发人员通过执行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

FizzBu​​zz Kata与Java流相关推荐

  1. kata_FizzBu​​zz Kata与Java流

    kata 在柔道练习仅几周之后,我的儿子感到无聊. 他抱怨说自己没有学任何东西,因为他一遍又一遍地做着同样的事情. 混淆学习和做新事物的不仅是幼儿. 例如,有多少软件开发人员通过执行kata或参加do ...

  2. Java中的功能性FizzBu​​zz Kata

    不久前,我使用Java 8流和lambda解决了FizzBu​​zz kata问题. 尽管最终结果是可行的,但中间步骤却没有. 我当然可以做得更好. 与往常一样,让我们​​从失败的测试开始: pack ...

  3. kata_Java中的功能性FizzBu​​zz Kata

    kata 不久前,我使用Java 8流和lambda解决了FizzBu​​zz kata问题. 尽管最终结果是可行的,但中间步骤却没有. 我当然可以做得更好. 与往常一样,让我们​​从失败的测试开始: ...

  4. mockito_使用FizzBu​​zz和Mockito进行单元测试

    mockito 我有时使用FizzBu​​zz向新手演示单元测试的基础. 尽管FizzBu​​zz确实是一个简单的问题,但是它也可以用于演示更高级的单元测试技术,例如模拟. FizzBu​​zz Ka ...

  5. mockito 单元测试_使用FizzBu​​zz和Mockito进行单元测试

    mockito 单元测试 我有时使用FizzBu​​zz向新手演示单元测试的基础. 尽管FizzBu​​zz确实是一个简单的问题,但它也可以用于演示更高级的单元测试技术,例如模拟 . FizzBu​​ ...

  6. 使用FizzBu​​zz和Mockito进行单元测试

    我有时使用FizzBu​​zz向新手演示单元测试的基础. 尽管FizzBu​​zz确实是一个简单的问题,但是它也可以用于演示更高级的单元测试技术,例如模拟 . FizzBu​​zz Kata: &qu ...

  7. java流类图结构_java I/O 流总结

    一.java 流操作有关的类和接口: 类                                                                          说明 Fil ...

  8. java文件流插入数据库_使用Java流查询数据库

    java文件流插入数据库 在本文中,您将学习如何编写纯Java应用程序,这些应用程序能够处理现有数据库中的数据,而无需编写一行SQL(或类似的语言,例如HQL),而无需花费数小时将所有内容放在一起. ...

  9. jvm优化_使用Java流和In-JVM-Memory的超低延迟查询

    jvm优化 自然界的基本规则(例如光速和通用信息论)对我们可以从传统系统体系结构中获得的最大性能设置了明显的限制. 了解您作为Java开发人员如何使用JVM技术和Java流将性能提高几个数量级. 例如 ...

最新文章

  1. 一线互联网Top20高频面试题曝光!
  2. 华为服务器故障灯不开机_总有故障灯亮却不知道是怎么回事?详解这些你不认识的故障灯...
  3. 三、前端开发-CSS
  4. springMVC简单实例
  5. 小学计算机教师交流计划,2023年小学计算机教师工作计划
  6. [转]Eclipse工具使用技巧总结
  7. 三菱5uplc伺服电机指令_【工控无忧原创】三菱FX3U PLC如何控制松下伺服
  8. 【小知识】Elastic Search排除某个索引后缀
  9. 相对路径遍历Relative Path Traversal
  10. html中pc端与移动端区别,盘点移动端和PC端交互设计上的区别
  11. 使用 Marvelous Designer 为DAZ Studio 的 Genesis8 Female做衣服 1
  12. 广义相对论-学习记录3-第二章-狭义相对论2
  13. win10 关闭自动维护计划任务
  14. Rasa课程、Rasa培训、Rasa面试、Rasa实战系列之 Model Confidence v2
  15. 网络服务器是指带有大容量硬盘的计算机,中国人民大学网络教育201812统考计算机模拟题...
  16. 主板有电无法启动_电脑主板通电但是开不了机是什么原因?
  17. 比尔.盖兹另辟Vista新战场?
  18. 51单片机实战教程(32 人机界面编程9)
  19. PAT 1025 PAT Ranking题解
  20. java多线程高级:JUC

热门文章

  1. java使用循环案例——CSDN博客
  2. 2015蓝桥杯省赛---java---A---8(移动距离)
  3. 三星系统和鸿蒙系统,又一设备直升鸿蒙系统,现有操作系统被抛弃,和三星的想法一样!...
  4. getSerializableExtra
  5. java异常了还会往下走吗_异常一个问题,请帮下忙:处理异常后,程序会继续往下运行吗...
  6. linux 提取cpio_15. Linux提取RPM包文件(cpio命令)详解
  7. XML——XSLT的一个简单荔枝
  8. quarkus_使用Quarkus调试容器中的系统测试(视频)
  9. 使用junit进行单元测试_使用JUnit5对DynamoDB应用程序进行单元测试
  10. spock 集成测试_Spock 1.2 –轻松进行集成测试中的Spring Bean模拟