Even i Odd, czyli DRY in Action 2

Przeglądam ostatnio jakiś stary moduł do softu, który piszę. Trafiłem na ciekawy przypadek złamania zasady DRY. W poprzednim wpisie opisałem czym jest ta zasada. Dla przypomnienia DRY, czyli skrót od angielskiego Don’t Repeat Yourself jest zasadą dobrego programowania, która mówi, żeby unikać powtórzeń kodu. Pozwala to na lepsze zarządzanie kodem (dokładnie zmianą kodu) i tym samym lżejsze życie programistów i supportu.
Dość częstym błędem związanym z DRY jest przetwarzanie warunkowe z powtórzeniem kodu. koronnym przypadkiem jest kolorowanie wierszy parzystych i nieparzystych. Poniżej bardzo zły kod wykonujący to zadanie.

Listing 1. Zły pomysł

if (lp % 2 == 0) {
	_lpLbl.setStyleName("result-table-even");
	_clrrunLbl.setStyleName("result-table-even");
	_clrdayLbl.setStyleName("result-table-even");
	_brnorgidtLbl.setStyleName("result-table-even");
	_brnrcvidtLbl.setStyleName("result-table-even");
	_msgsubgrpLbl.setStyleName("result-table-even");
	_doktypLbl.setStyleName("result-table-even");
	_pointerLbl.setStyleName("result-table-even");
	_msgvolLbl.setStyleName("result-table-even");
	_msgvalLbl.setStyleName("result-table-even");
} else {
	_lpLbl.setStyleName("result-table-odd");
	_clrrunLbl.setStyleName("result-table-odd");
	_clrdayLbl.setStyleName("result-table-odd");
	_brnorgidtLbl.setStyleName("result-table-odd");
	_brnrcvidtLbl.setStyleName("result-table-odd");
	_msgsubgrpLbl.setStyleName("result-table-odd");
	_doktypLbl.setStyleName("result-table-odd");
	_pointerLbl.setStyleName("result-table-odd");
	_msgvolLbl.setStyleName("result-table-odd");
	_msgvalLbl.setStyleName("result-table-odd");
}

Znacznie prostszym rozwiązaniem w tym przypadku jest użycie zmiennej lokalnej:

Listing 2. Lepsze rozwiązanie

String el = lp % 2 == 0 ? "even" : "odd";
_lpLbl.setStyleName("result-table-" + el);
_clrrunLbl.setStyleName("result-table-" + el);
_clrdayLbl.setStyleName("result-table-" + el);
_brnorgidtLbl.setStyleName("result-table-" + el);
_brnrcvidtLbl.setStyleName("result-table-" + el);
_msgsubgrpLbl.setStyleName("result-table-" + el);
_doktypLbl.setStyleName("result-table-" + el);
_pointerLbl.setStyleName("result-table-" + el);
_msgvolLbl.setStyleName("result-table-" + el);
_msgvalLbl.setStyleName("result-table-" + el);

Dlaczego nie Strategia

Jeszcze lepszym rozwiązaniem jest użycie wzorca strategii. Z drugiej strony jeżeli mamy problem w którym warunek ma naturę binarną to wprowadzanie dodatkowego wzorca projektowego jest tylko niepotrzebnym komplikowaniem kodu. Jeżeli warunek trzeba by było rozszerzyć dla np. 3 rodzajów rekordów to dopiero w tym momencie należy wprowadzić dodatkowy wzorzec.

2 Responses to “Even i Odd, czyli DRY in Action 2”

  1. Tomek Says:

    hello,

    tylko po co x razy dodajesz w kółko te same dwa stringi: “result-table-” + el ?


    pozdrawiam
    Tomek Kaczanowski

  2. Koziolek Says:

    Bo przykład został “zanonimizowany” i wyleciał początek z każdego stringa. Ale racja, jeżeli był by to pełen przykład operacja dodawania powinna odbyć się tylko raz.

Leave a Reply