Witam,
w tej części serii chciałbym przedstawić wam zasadę używaną w programowaniu. Jest to zasada DRY. Rozwinięcie tego skrótu, to "Don't Repeat Yourself", czyli "Nie powtarzaj się".
Zastanówmy się w jakim celu została wymyślona ta zasada i jak możemy ją zastosować w naszym kodzie.
Jako programiści, powinniśmy wiedzieć, że powtórzenia w kodzie powodują niepotrzebne bugi(błędy w programie). Spytacie dlaczego? Jednym z powodów jest zmiana pewnej instrukcji w jednym miejscu i zapomnienie zmiany tej samej instrukcji w innym miejscu. No przecież my tylko użyliśmy zasady kopiego pejsta (copy + paste code). No niestety, gdy mam powielony ten sam kod i ilość tego kodu jest spora, to bardzo łatwo zapomnieć tego poprawić.
No to jak to możemy poprawić?
Nasze środowisko programistyczne (IDE) powinno posiadać pewne narzędzia wspomagające naszą pracę. Np. takie, aby wyciągnąć powtórzony kod i wrzucić go do np. osobnej metody albo do osobnej zmiennej, a nawet do osobnej klasy. Jeżeli takich narzędzi nie mamy, to powinniśmy trzymać się pewnego rygoru(np. zastosowanie TDD, czyli Test Driven Development). To co mam na myśli jest, żeby napisaną funkcjonalność w programie "zrefactoryzować". Refactoring, to czynność porządkowania kodu, bez zmiany jego działania.
No dobra, to pokażę teraz taki kod, który będzie wymagał refactoryzacji.
Weźmy na tapetę trywialny przykład:
public static void main(String[] args) {
int sum = 0;
int a = 2101;
int b = 5;
sum = a + b;
System.out.println("Suma wartości to " + sum);
a = 5;
b = 10;
sum = a + b;
System.out.println("Suma wartości to " + sum);
a = 32034;
b = 2948;
sum = a + b;
System.out.println("Suma wartości to " + sum);
}
Jak widzimy, mamy powtarzający się gdzie przypisujemy jakieś dwie liczby, sumujemy je i wyświetlamy na eranie.
Spróbujmy użyć teraz wyciągnięcia jakieś wspólnej metody, która pozwoli na pozbycie się tego ciągłego sumowania. Użyje w Intellij IDEA takiego narzędzia jak "extract method".
Pierwsze co robię to zaznaczam:
sum = a + b;
Następnie klikam na zaznaczenie prawym klawiszem myszki, przesuwam kursor na extract, potem na method. W oknie możemy dostosować jak ma wyglądać nazwa i parametry metody, ale my akceptujemy jak jest zmieniając tylko nazwę.
Po wykonaniu tego kroku IDE powinno nam pokazać, że w kodzie posiadamy jeszcze dwa powtórzenia tego samego kodu, a następnie spyta czy chcemy zastosować utworzoną metodę także w tamtym miejscu.
Po refactoryzacji, nasz kod powinien wyglądać mniej więcej tak:
public class Main {
public static void main(String[] args) {
int sum = 0;
int a = 2101;
int b = 5;
sum = getSum(a, b);
System.out.println("Suma wartości to " + sum);
a = 5;
b = 10;
sum = getSum(a, b);
System.out.println("Suma wartości to " + sum);
a = 32034;
b = 2948;
sum = getSum(a, b);
System.out.println("Suma wartości to " + sum);
}
private static int getSum(int a, int b) {
int sum;
sum = a + b;
return sum;
}
}
Jak widzimy możemy zrobić jeszcze porządek ze zmiennymi i wyciągnąć metodę do wyświetlania sumy:
public class Main {
public static void main(String[] args) {
int sum = 0;
sum = getSum(2101, 5);
printSum(sum);
sum = getSum(5, 10);
printSum(sum);
sum = getSum(32034, 2948);
printSum(sum);
}
private static void printSum(int sum) {
System.out.println("Suma wartości to " + sum);
}
private static int getSum(int a, int b) {
int sum;
sum = a + b;
return sum;
}
}
Widzimy także, że nasza metoda getSum można uprościć:
public class Main {
public static void main(String[] args) {
int sum = 0;
sum = getSum(2101, 5);
printSum(sum);
sum = getSum(5, 10);
printSum(sum);
sum = getSum(32034, 2948);
printSum(sum);
}
private static void printSum(int sum) {
System.out.println("Suma wartości to " + sum);
}
private static int getSum(int a, int b) {
return a + b;
}
}
No i ostatnie co możemy zrobić z kodem, to wyciągnąć "Suma wartości to " do pola. Dzięki temu nie będziemy musieli później szukać tego napisu w kodzie, gdybyśmy chcieli coś zmienić (np. brak przecinka przed "to" :)):
Aby zrobić to sprawnie możemy wyekstraktować pole czyli zaznaczamy tekst, klikamy prawym klawiszem myszy na extract, field. Zaznaczmy, że chcemy wrzucać nasz napis przy tworzeniu zmiennej ("field initialization"). Następnie nadajemy nazwę naszej zmiennej i akceptujemy.
Nasz kod na końcu powinien wyglądać tak:
public class Main {
private static final String text = "Suma wartości to ";
public static void main(String[] args) {
int sum = 0;
sum = getSum(2101, 5);
printSum(sum);
sum = getSum(5, 10);
printSum(sum);
sum = getSum(32034, 2948);
printSum(sum);
}
private static void printSum(int sum) {
System.out.println(text + sum);
}
private static int getSum(int a, int b) {
return a + b;
}
}
Mógłbym omówić wam jeszcze ekstrakcję zmiennej, ale możecie to sami zrobić i wyciągnąć zmienną w metodzie getSum w celu "przećwiczenia".
Jak mówiłem wcześniej, przykład jest trywialny(prosty). Żeby pokazać wam coś bardziej skomplikowanego, to musiałbym poszukać jakiś kod z moich projektów, gdzie klasa wymagałaby refactoryzacji.
Mam nadzieję, że zamysł refactoryzowania kodu, został w tym poscie sensownie ujęty.
Jeżeli czegoś nie rozumiecie, albo chcielibyście abym coś poprawił, to piszcie w komentarzach. Tak czy inaczej, zapraszam do oceny :)