Zasada DRY - kiedy naprawdę pomaga, a kiedy szkodzi?

Kobieta w okularach pracuje przy komputerze, na ekranie mapa świata i linie kodu.

Napisano przez

Tymoteusz Sobczak

Opublikowano

24 maj 2026

Spis treści

W dobrze prowadzonym projekcie webowym najdroższe nie są pojedyncze linie kodu, tylko rozlana po wielu miejscach wiedza biznesowa. Gdy reguła walidacji, format daty albo mapa statusów żyją w kilku plikach, każda zmiana zaczyna kosztować więcej niż powinna. Ten tekst pokazuje, jak rozumieć dry code w praktyce, gdzie ta zasada naprawdę pomaga, kiedy prowadzi do lepszej architektury i kiedy lepiej chwilę poczekać z abstrakcją.

Najkrótsza wersja zasady, zanim wejdziesz w szczegóły

  • DRY dotyczy przede wszystkim wiedzy, a nie samego liczenia identycznych linii kodu.
  • Najwięcej problemów powoduje duplikacja reguł biznesowych, walidacji, mapowań i konfiguracji.
  • Nie każda powtórka jest błędem - czasem lepiej chwilowo powielić prosty fragment niż zbudować złą abstrakcję.
  • Najbezpieczniej refaktoryzować dopiero wtedy, gdy widać wspólny wzorzec zmiany, a nie tylko podobieństwo składni.
  • W architekturze i wzorcach dobrze działają m.in. Strategy, Factory, Adapter, Specification i warstwa mapująca.
  • Źródło prawdy powinno być jedno, ale jego miejsce trzeba dobrać do domeny, a nie do wygody chwilowego refaktoru.

Co naprawdę oznacza zasada DRY

Najczęstsze nieporozumienie jest banalne: wiele osób myśli, że chodzi o zakaz kopiowania kodu. To za proste. Chodzi o to, by ta sama wiedza nie była zapisana w kilku miejscach, bo wtedy każda zmiana staje się ryzykowna. Jeśli reguła istnieje raz, łatwiej ją zmienić, przetestować i utrzymać w zgodzie z resztą systemu.

Ja patrzę na to tak: jeśli zmiana biznesowa wymaga poprawienia trzech plików, to wiedza o tej regule nie ma jeszcze jednego właściciela. W projektach webowych widać to szczególnie wyraźnie w walidacji formularzy, statusach encji, mapowaniu DTO, konfiguracji środowisk i komunikatach błędów. Z zewnątrz wszystko wygląda podobnie, ale z punktu widzenia utrzymania to zupełnie inna sprawa niż zwykłe powtórzenie kilku linii.

Ważny detal: identyczny zapis nie zawsze oznacza identyczną intencję. Dwa podobne warunki `if` mogą wyglądać jak duplikat, ale jeśli sterują różnymi przypadkami użycia, ich wspólne wyciągnięcie może tylko zaciemnić kod. To właśnie dlatego DRY trzeba czytać razem z kontekstem domeny, a nie wyłącznie przez pryzmat edytora tekstu. Na tej podstawie łatwiej zobaczyć, gdzie duplikacja naprawdę szkodzi, a gdzie jeszcze nie ma sensu jej ruszać.

Gdzie duplikacja najczęściej psuje projekt

W praktyce najwięcej strat nie robią drobne powtórki, tylko miejsca, w których ta sama reguła zaczyna żyć równolegle w kilku warstwach aplikacji. W projektach webowych widzę to najczęściej w poniższych obszarach.

Miejsce Co zwykle się powiela Lepsze rozwiązanie
Walidacja formularzy Długość hasła, format maila, wymagane pola i komunikaty błędów w kilku komponentach Jedna wspólna definicja reguł, a osobno warstwa prezentacji
Backend i frontend Te same ograniczenia w React i w API, ale zapisane niezależnie Serwer jako źródło prawdy, frontend jako warstwa UX i wczesnej walidacji
Mapowanie obiektów Powtarzane przypisania `user.name`, `user.email`, `user.role` w wielu miejscach Oddzielny mapper lub adapter, który zna zasady transformacji
Konfiguracja i stałe Te same ścieżki, statusy, limity i identyfikatory wpisane ręcznie w wielu plikach Jedno centralne źródło konfiguracji lub moduł z domenowymi stałymi
Testy Skopiowane fixture i dane wejściowe, które różnią się tylko jednym polem Fabryka testowa albo helper budujący scenariusze

Najciekawsze jest to, że duplikacja w tych miejscach często długo nie boli. Boli dopiero wtedy, gdy produkt rośnie, dochodzą kolejne przypadki użycia i nagle jedna zmiana wymaga ręcznego poprawiania czterech warstw. Właśnie wtedy DRY przestaje być teorią, a zaczyna być oszczędnością czasu. Dalej pokazuję, jak stosować tę zasadę bez wpadania w pułapkę nadmiernego uogólniania.

Cykl TDD: czerwony (napisz test), zielony (napisz kod), refaktoryzacja (optymalizuj, by uniknąć dry code).

Jak stosować DRY bez sztucznych abstrakcji

Najgorsze, co można zrobić, to zobaczyć podobieństwo i od razu zbudować wspólny helper. To zwykle kończy się funkcją, która przyjmuje za dużo parametrów, ma kilka flag logicznych i po miesiącu nikt nie pamięta, dlaczego w ogóle istnieje. DRY ma upraszczać zmianę, a nie dokładać kolejną warstwę pośrednią.

  1. Sprawdź, co naprawdę się powtarza. Nie szukaj identycznych znaków, tylko tej samej reguły biznesowej. Dwa podobne fragmenty mogą opisywać coś innego.
  2. Zastanów się, co zmienia się razem. Jeśli przy każdej zmianie produktu rusza ten sam warunek, ten sam komunikat i ta sama walidacja, to masz dobry kandydat na centralizację.
  3. Wyciągaj tylko stabilny fragment. Nie rób jednego uniwersalnego potwora. Jeśli wspólna jest tylko część logiki, zacznij od małej funkcji, klasy pomocniczej albo policy object.
  4. Nazywaj rzeczy domenowo. Zamiast `helper1` lepiej użyć nazwy, która mówi, jaką wiedzę przechowuje. Nazwa ma pomóc przyszłemu tobie szybciej znaleźć źródło prawdy.
  5. Weryfikuj po refaktorze. Po wyciągnięciu wspólnego fragmentu uruchom testy i sprawdź, czy nowa abstrakcja nie wymaga już wyjątków, obejść i dodatkowych parametrów.

W praktyce dobrze działa prosty heurystyczny filtr: pierwszy raz kod piszę bez presji na generyczność, drugi raz zaznaczam sobie potencjalne powtórzenie, a przy trzecim podobnym miejscu zwykle refaktoryzuję. To nie jest prawo fizyki, tylko zdrowy próg decyzyjny. Dzięki temu nie marnuję czasu na zgadywanie abstrakcji, zanim zobaczę, że wzorzec naprawdę się utrwalił. A kiedy już go widać, można sięgnąć po wzorce i elementy architektury, które ten porządek utrzymują.

Jakie wzorce i elementy architektury wspierają DRY

DRY rzadko działa samodzielnie. W praktyce wspierają go konkretne wzorce projektowe i sensownie rozdzielone warstwy. Nie chodzi o to, żeby na siłę wstawiać wzorzec wszędzie, tylko o to, żeby centralizować wiedzę tam, gdzie ma to sens.
Sytuacja Wzorzec lub element architektury Co centralizuje Na co uważać
Różne reguły biznesowe dla podobnych przypadków Specification / Policy Warunki decyzyjne i reguły domenowe Nie mieszaj reguł z prezentacją ani z transportem danych
Tworzenie obiektów z powtarzalną inicjalizacją Factory / Builder Sposób budowy obiektów i ustawiania domyślnych wartości Nie rozbudowuj fabryki do poziomu, w którym zaczyna wiedzieć za dużo
Przejście między warstwami aplikacji Adapter / Mapper Transformację danych między API, domeną i UI Uważaj, żeby mapper nie stał się drugim serwisem domenowym
Warianty zachowania przy wspólnym interfejsie Strategy Algorytm, który się zmienia, ale jest wybierany w jednym miejscu Nie twórz strategii dla dwóch prostych ifów
Wspólny przebieg procesu z drobnymi różnicami Template Method Szkielet operacji i punkty rozszerzeń Jeśli różnic jest dużo, lepsze może być rozbicie procesu na mniejsze kroki

W architekturze warstwowej dobrze działa też prosta zasada: kontrolery nie powinny dublować reguł serwisów, a serwisy nie powinny dublować logiki domenowej w kilku miejscach. Gdy walidacja jest potrzebna zarówno w API, jak i w panelu administracyjnym, najlepiej trzymać regułę w jednym module, a na brzegu systemu zostawić jedynie walidację techniczną lub komunikaty dla użytkownika. To daje realny porządek, a nie tylko wrażenie czystości. Jednak nawet wtedy trzeba uważać, żeby nie stworzyć zbyt ciężkiej abstrakcji, bo nie każda powtórka jest zła.

Kiedy powtórzenie jest lepsze niż zła abstrakcja

To jest moment, w którym wiele osób zaczyna przesadzać w drugą stronę. Zobaczą dwa podobne fragmenty i natychmiast chcą je scalić. Ja wolę najpierw odpowiedzieć sobie na jedno pytanie: czy to naprawdę jest ta sama wiedza, czy tylko podobny kształt kodu? Jeśli odpowiedź nie jest oczywista, bezpieczniej zostawić lokalne powtórzenie.

Tu dobrze pasuje heurystyka znana jako rule of three: dwa podobne fragmenty jeszcze nie muszą wymagać refaktoru, ale trzeci zwykle pokazuje, że wzorzec jest już wystarczająco wyraźny. To nadal tylko reguła kciuka, nie dogmat. W praktyce czasem refaktoryzuję wcześniej, jeśli zmiana już teraz boli, a czasem celowo czekam, bo potrzebuję zobaczyć więcej przykładów.

  • Duplikacja może być dobra, gdy kod jest eksperymentalny, krótkotrwały albo jeszcze nie wiadomo, jak będzie się rozwijał.
  • Duplikacja jest akceptowalna, gdy dwie ścieżki są podobne tylko powierzchownie, ale mają inne źródła zmian.
  • Zła abstrakcja wychodzi na jaw, gdy zaczynasz dodawać flagi `if/else`, opcjonalne parametry i obejścia tylko po to, by jeden helper obsłużył wszystko.
  • Wspólny kod ma sens, gdy powtarza się ta sama reguła biznesowa, a nie tylko podobna składnia.
Dobry sygnał ostrzegawczy jest prosty: jeśli wspólna funkcja zaczyna mieć 6-7 parametrów, a każdy nowy przypadek wymaga kolejnego wyjątku, to prawdopodobnie abstrahujesz za wcześnie albo za szeroko. Wtedy lepiej cofnąć się o krok, dopuścić lokalne powtórzenie i poszukać mniejszej, bardziej domenowej granicy wspólnoty. Z tego wynika naturalnie pytanie, jak utrzymać taki porządek w zespole, a nie tylko w jednym pliku.

Jak utrzymać spójność w zespole i w repozytorium

DRY nie wygrywa samym stylem kodowania. Wygrywa wtedy, gdy zespół ma wspólne zasady, gdzie jest źródło prawdy i kiedy wolno je powielić lokalnie. Bez tego nawet dobre intencje kończą się kolekcją helperów, które każdy rozumie trochę inaczej.

  1. Ustal jedno miejsce dla reguł domenowych. Jeśli walidacja zamówienia jest ważna dla kilku ekranów i endpointów, nie chowaj jej w pięciu komponentach.
  2. Dodaj testy wokół wspólnej logiki. Im bardziej centralny fragment, tym bardziej opłaca się go zabezpieczyć testami jednostkowymi i kontraktowymi.
  3. Przeglądaj pull requesty pod kątem wiedzy, nie tylko wyglądu. Dobrze jest zapytać: gdzie będzie trzeba to zmienić za miesiąc?
  4. Nie kopiuj konfiguracji między środowiskami. Jedna definicja stałych i jeden mechanizm nadpisywania są bezpieczniejsze niż ręczne przepisywanie wartości.
  5. Dokumentuj wyjątki. Jeśli świadomie zostawiasz powtórzenie, wpisz krótko dlaczego. To oszczędza dyskusje po drodze i chroni przed „ulepszeniem” czegoś, co było celowe.

W większych zespołach dochodzi jeszcze kwestia granic między modułami. Jeśli współdzielony pakiet zaczyna rosnąć szybciej niż sam produkt, to znak, że centralizacja poszła za daleko. Wtedy lepiej rozbić wiedzę na mniejsze, domenowe kawałki niż trzymać wszystko w jednym „wspólnym” folderze. To właśnie takie decyzje odróżniają zdrowy DRY od kodu, który wygląda schludnie tylko na pierwszy rzut oka. Na koniec zostaje najważniejsze pytanie: co z tego realnie zapamiętać, gdy wrócisz do własnego projektu?

Najbezpieczniejsza reguła pracy z powtórzeniami

Gdybym miał zostawić jedną praktyczną myśl, byłaby bardzo prosta: najpierw centralizuj wiedzę, dopiero potem skracaj kod. Właśnie ta kolejność chroni przed błędami, które najczęściej niszczą sens DRY - przedwczesną abstrakcją, zbyt ogólnym helperem i ukrywaniem reguł w miejscach, których nikt potem nie odważy się ruszyć.

  • Jeśli zmiana w jednym miejscu wymaga poprawienia 2-3 plików, szukaj wspólnego źródła.
  • Jeśli wspólny fragment zaczyna mieć wyjątki, sprawdź, czy nie próbujesz połączyć różnych problemów.
  • Jeśli kod jest nadal odkrywany, zostaw lokalne powtórzenie i wróć do refaktoru później.
  • Jeśli reguła jest krytyczna dla biznesu, trzymaj ją możliwie blisko domeny, a nie w przypadkowym helperze.
W praktyce najlepiej działa kod, który jest wystarczająco suchy, by zmieniać go w jednym miejscu, ale nie tak „wygładzony”, żeby zgubić sens domeny. To jest właśnie zdrowe podejście do DRY w architekturze i wzorcach: mniej kopiowania wiedzy, więcej świadomych granic i prostsze decyzje przy kolejnej zmianie.

FAQ - Najczęstsze pytania

DRY (Don't Repeat Yourself) oznacza, by ta sama wiedza nie była zapisana w wielu miejscach. Chodzi o unikanie duplikacji reguł biznesowych, walidacji czy konfiguracji, a nie tylko identycznych linii kodu. Celem jest łatwiejsze utrzymanie i modyfikacja systemu.

Duplikacja jest akceptowalna, gdy kod jest eksperymentalny, krótkotrwały lub gdy podobne fragmenty mają inne intencje i źródła zmian. Czasem lepiej powtórzyć prosty fragment niż tworzyć złą, zbyt skomplikowaną abstrakcję, która później generuje problemy.

Wspierają ją m.in. Strategy (dla wariantów zachowania), Factory/Builder (dla tworzenia obiektów), Adapter/Mapper (dla transformacji danych) oraz Specification/Policy (dla reguł biznesowych). Pomagają one centralizować wiedzę i logikę w jednym miejscu.

Aby uniknąć złych abstrakcji, refaktoryzuj dopiero, gdy widzisz wspólny wzorzec zmiany, a nie tylko podobieństwo składni. Zaczynaj od małych, domenowych funkcji, nazywaj je jasno i weryfikuj po refaktorze, czy nowa abstrakcja nie wymaga wyjątków i obejść.

W projektach webowych DRY jest kluczowe, bo wiedza biznesowa często rozlewa się po wielu warstwach (frontend, backend, walidacja). Centralizacja reguł pozwala na szybsze zmiany, redukuje ryzyko błędów i znacznie obniża koszty utrzymania systemu, gdy projekt rośnie.

Oceń artykuł

Ocena: 0.00 Liczba głosów: 0

Tagi:

dry code zasada dry w programowaniu dry code w praktyce jak stosować zasadę dry kiedy stosować zasadę dry dry a architektura oprogramowania

Udostępnij artykuł

Tymoteusz Sobczak

Tymoteusz Sobczak

Nazywam się Tymoteusz Sobczak i mam 9-letnie doświadczenie w programowaniu webowym. Moja przygoda z tą dziedziną zaczęła się od fascynacji tworzeniem stron internetowych, co z czasem przerodziło się w pasję do dzielenia się wiedzą i pomagania innym w odkrywaniu tajników programowania. Lubię wyjaśniać złożone zagadnienia w przystępny sposób, co pozwala moim czytelnikom lepiej zrozumieć temat i rozwijać swoje umiejętności. Pisząc dla jscwiczenia.pl, koncentruję się na dostarczaniu aktualnych i rzetelnych informacji, które są zrozumiałe nawet dla osób dopiero zaczynających swoją przygodę z programowaniem. Staram się porównywać różne źródła, śledzić najnowsze trendy i organizować wiedzę w sposób, który ułatwia naukę. Moim celem jest, aby każdy mógł znaleźć tu przydatne materiały, które pomogą mu w budowaniu kariery w programowaniu webowym.

Napisz komentarz