Godzina 5.00, za oknami ciemno, pora na codzienne ćwiczenia. Zgodnie z definicją: “Kata – wysoce sformalizowany rodzaj ćwiczeń stosowanych w wielu tradycyjnych sztukach i sportach walki…”, “Są to sekwencje technik ataku i obrony, połączone z określonym poruszaniem, przyjęciem ściśle określonej pozycji i sposobu oddychania. Niektóre techniki w kata mają charakter wyłącznie symboliczny.”
Kata w kontekście IT to codzienne krótkie ćwiczenia (najlepiej do 30 minut), w których wykonujemy powtarzalne czynności. W ciągu tych ćwiczeń rozwiązujemy dowolne zadanie jak na przykład opisane poniżej FizzBuzz. Podczas treningu używamy skrótów, składni języka, gita czy specyficznych frameworków. Takie codzienne powtarzanie czynności pozwala nam być zawsze w “formie”. Kata są także dobrym rozwiązaniem do nauki nowej technologii. Cykliczne powtarzanie utrwala w naszej głowie mechanizmy specyficzne dla danej technologii.
FizzBuzz jest szybkim ćwiczeniem często stosowanym na rozmowach kwalifikacyjnych, aby sprawdzić jak kandydat porusza się w IDE oraz jakie stosuje podejście przy programowaniu. Ćwiczenie to jest także często wykonywane w połączeniu z TDD.
- Wypisz wszystkie liczby od 1 do 100
- Jeśli liczba jest podzielna przez trzy wypisz “Fizz“
- Jeśli liczba jest podzielna przez pięć wypisz “Buzz“
- Jeśli liczba jest podzielna przez trzy i pięć wypisz “FizzBuzz“
Moja proponowana implementacja w Javie:
public class FizzBuzzTest { private FizzBuzz fizzBuzz = new FizzBuzz(); //Should return 'Fizz' when number is divisible by three @Test public void shouldReturnFizzWhenNumberIsDivisibleByThree() throws Exception { // When String result = fizzBuzz.check(3); // Then assertThat(result).contains("Fizz"); } //Should return 'Buzz' when number is divisible by five @Test public void shouldReturnBuzzWhenNumberIsDivisibleByFive() throws Exception { // When String result = fizzBuzz.check(5); // Then assertThat(result).contains("Buzz"); } //Should return 'FizzBuzz' when number is divisible by five @Test public void shouldReturnFizzBuzzWhenNumberIsDivisibleByFiveAndThree() throws Exception { // When String result = fizzBuzz.check(15); // Then assertThat(result).contains("FizzBuzz"); } //Should return number when number is not divisible by five and three @Test public void shouldReturnNumberWhenNumberIsNotDivisibleByFiveAndThree() throws Exception { // When String result = fizzBuzz.check(1); // Then assertThat(result).contains("1"); } private class FizzBuzz { static final String FIZZ = "Fizz"; static final String BUZZ = "Buzz"; String check(int number) { String result = ""; if(isDividedByThree(number)){ result+= FIZZ; } if(isDividedByFive(number)){ result+= BUZZ; } return result.isEmpty() ? String.valueOf(number) : result; } private boolean isDividedByFive(int number) { return number%5==0; } private boolean isDividedByThree(int number) { return number%3==0; } } }
Moja proponowana implementacja w Spocku:
class FizzBuzzSpec extends Specification { @Shared def fizzBuzz = new FizzBuzz() def "Should return 'Fizz' when number is divisible by three" (){ when: def result = fizzBuzz.check(3) then: result == "Fizz" } def "Should return 'Buzz' when number is divisible by five" (){ when: def result = fizzBuzz.check(5) then: result == "Buzz" } def "Should return 'FizzBuzz' when number is divisible by five and three" (){ when: def result = fizzBuzz.check(15) then: result == "FizzBuzz" } @Unroll def "Should return #excpectedValue when number is divisible by #number" (){ when: def result = fizzBuzz.check(number) then: result == excpectedValue where: number || excpectedValue 1 || "1" 3 || "Fizz" 5 || "Buzz" 15 || "FizzBuzz" } class FizzBuzz{ String check(int number) { def result = "" if(isDividedByThree(number)){ result+= "Fizz" } if(isDividedByFive(number)){ result+="Buzz" } return result.isEmpty() ? String.valueOf(number) : result } private boolean isDividedByFive(int number) { number % 5 == 0 } private boolean isDividedByThree(int number) { number % 3 == 0 } } }
Całość jak zawsze na GitHubie.