kata_FizzBuzz Kata与Java流
kata
在柔道練習僅幾周之后,我的兒子感到無聊。 他抱怨說自己沒有學任何東西,因為他一遍又一遍地做著同樣的事情。
混淆學習和做新事物的不僅是幼兒。 例如,有多少軟件開發人員通過執行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));}}請注意for和if語句如何消失。 而不是拼寫出的東西需要如何做,我們說什么 ,我們要實現的。
我們可以應用相同的技巧來除去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
kata
總結
以上是生活随笔為你收集整理的kata_FizzBuzz Kata与Java流的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: drools6.5_Drools 6.4
- 下一篇: 使用充电宝注意哪些事项