DRY – Don’t repeat yourself
Jedna z najprostszych i zarazem najtrudniejsza w zastosowaniu zasada. Jeżeli spojrzymy na klasę i jej metody – zastosowanie tej zasady jest banalne. Wystarczy nie duplikować wielokrotnie tej samej logiki. Natomiast jeżeli spojrzymy trochę wyżej to zasada DRY odnosi się do nie duplikowania wiedzy. Według tej zasady:
Każdy wycinek wiedzy musi mieć dokładnie jedną, jednoznaczną i oficjalną reprezentację w ramach systemu.
Jak powstaje powielenie?
Przez narzucenie
Czujemy, że nie mamy wyboru. Wydaje nam się, że zostaliśmy zmuszeni przez sytuację do powielania wiedzy.
Niemuślnie
Nie zdajemy sobie sprawy (np. jesteśmy nowi w projekcie) i powielamy jakąś informację, która jest już gdzieś zapisana.
Przez niecierpliwość
Tak na prawdę powinienem napisać przez lenistwo. Często wiemy, że dana informacja jest już gdzieś zapisana i moglibyśmy to spróbować tą rozproszoną wiedzę zebrać w jednym miejscu ale przez nasze lenistwo dokładamy cegiełkę i powielamy to co już jest.
Zespołowo
Najczęściej jest to problem komunikacji między zespołami. Kilka zespołów pracuje nad jednym systemem i powielają tą samą wiedzę wielokrotnie w ramach tego samego systemu.
Do czego prowadzi powielanie logiki?
Najczęściej do dużych problemów, wtedy gdy logika się zmieni. Dla przykładu gdy logikę walidacji użytkownika umieścimy w jednym miejscu to jeżeli dodamy jakiś dodatkowy status, który musimy obsłużyć to tylko w tym jednym miejscu będziemy musieli zareagować na zmiany. Pamiętam system w którym dodanie nowego rodzaju kodu rabatowego dla produktów zajęło miesiąc – właśnie z takiego powodu, że jego logika walidacji była rozsiana po całym systemie.
Powielony kod często wymaga wielu komentarzy (zwłaszcza jeżeli jakiś warunek jest nieoczywisty). Z czasem warunki i logika się zmieniają ale przez to, że mamy ten sam kod zduplikowany w wielu miejscach to często komentarze nie zaktualizują się razem z kodem. Zdezaktualizowanie komentarze są gorsze niż ich brak. Jeżeli komentarzy nie ma – jesteśmy zmuszeni do analizowania kodu (ciężko nas okłamać bo widzimy co się dzieje). Jeżeli są komentarze a ich treść jest zdezaktualizowana – wprowadzą nas w błąd i mogą zdecydowanie wydłużyć nasz czas pracy.
Na co zwrócić uwagę?
Naszym celem powinno być stworzenie takiego środowiska (kodu), w którym znajdowanie i ponowne wykorzystanie istniejących rozwiązań będzie łatwiejsze niż samodzielne pisanie/kopiowanie identycznego kodu.
Jeżeli użycie naszych rozwiązań nie będzie dostatecznie proste, nikt nie będzie tego robił. Trzeba pamiętać, że jeśli istniejące rozwiązania nie są używane ponownie to ryzykujemy powieleniem wiedzy!
Czy zawsze stosować DRY?
No i tu leży cała trudność. Przedwczesne stosowanie zasady DRY, może prowadzić do zbędnych generalizacji. Najczęściej powtarzającym przykładem źle zrozumianego DRY (lub przedwcześnie zaimplementowanego) mogą być proste DTO. Załóżmy że mamy prostą klasę:
public class UserDto
{
public int Id { get; set; }
public string Name { get; set; }
public string Surname { get; set; }
}
Używamy jej do wszystkiego. Pobierania danych użytkownika, aktualizowania go i dodawania. Po jakimś czasie okazuje się, że model który używamy do pobrania użytkownika musi cos wyliczać (np. wiek na podstawie daty urodzenia). Potem okazuje się, że mieliśmy kolejny generyczny mechanizm przy dodawaniu usera żeby wszystkie property klasy nie były nullami. Kończy się to na wielu hackach, komentarzach, które tłumaczą dlaczego to jest tak zrobione i finalnie dochodzimy do momentu kiedy nie można tego już dłużej utrzymywać i trzeba to przepisać bo osoby, które to pisały już dawno w firmie nie pracują a kodu nikt nie rozumie.
Czy można było tego uniknąć? Tak. Wystarczyło stworzyć na samym początku 3 osobne klasy DTO, każda wyspecjalizowana w innej potrzebie (dodawanie, aktualizowanie, pobieranie).