Pokazywanie postów oznaczonych etykietą clean_code. Pokaż wszystkie posty
Pokazywanie postów oznaczonych etykietą clean_code. Pokaż wszystkie posty

poniedziałek, 21 kwietnia 2025

EA - Coupling i Kohezja

Każdy programista słyszał o zasadach dobrego kodu: czytelność, modularność, łatwość testowania, niskie koszty utrzymania. Ale jak je osiągnąć?



Jednym z fundamentów są dwa niepozorne, lecz kluczowe pojęcia: kohezja (cohesion) i sprzężenie (coupling).

W tym artykule wyjaśnię, czym są, jak wpływają na jakość systemu i pokażę praktyczne przykłady.

Coupling (sprzężenie)

Sprzężenie to miara zależności między modułami/kontrolerami/klasami.

  • Niskie sprzężenie (loose coupling) – moduły są niezależne, zmiana jednego nie powoduje efektu domina.

  • Wysokie sprzężenie (tight coupling) – zmiana w jednym komponencie wymusza zmiany w wielu innych, co utrudnia rozwój i testowanie.

Przykład wysokiego sprzężenia:


class OrderService { private final EmailService emailService = new EmailService(); public void placeOrder(Order order) { // logika zamówienia emailService.sendConfirmation(order.getUserEmail()); } }

OrderService tworzy instancję EmailService i staje się od niej zależny. Nie można tego łatwo przetestować, wymienić implementacji, ani odseparować.

Przykład niskiego sprzężenia (dobrze):


class OrderService { private final EmailService emailService; public OrderService(EmailService emailService) { this.emailService = emailService; } public void placeOrder(Order order) { // logika zamówienia emailService.sendConfirmation(order.getUserEmail()); } }

Tu zastosowano wstrzykiwanie zależności (Dependency Injection). OrderService nie obchodzi, jaka to implementacja EmailService. Dzięki temu łatwiej pisać testy, refaktoryzować i utrzymywać kod.

Cohesion (kohezja, spójność)

Kohezja to miara jak bardzo odpowiedzialności danego modułu są ze sobą powiązane.

  • Wysoka kohezja – klasa/metoda ma jedno konkretne zadanie.

  • Niska kohezja – klasa robi wszystko: zapisuje dane, wysyła e-maile, liczy podatki i jeszcze zapisuje logi...

Przykład niskiej kohezji:


class ReportManager { public void generateReport() { /* ... */ } public void sendReportByEmail() { /* ... */ } public void logReportToFile() { /* ... */ } public void calculateRevenue() { /* ... */ } }

Ta klasa ma wiele odpowiedzialności. Trudno ją rozszerzyć lub przetestować.

Przykład wysokiej kohezji (dobrze):


class ReportGenerator { public Report generate() { /* ... */ } } class ReportSender { public void send(Report report) { /* ... */ } } class RevenueCalculator { public BigDecimal calculate(Report report) { /* ... */ } }

Każda klasa ma jedno zadanie (Single Responsibility Principle) i dobrze współpracuje z innymi – ale nie jest z nimi nadmiernie powiązana. To przykład wysokiej kohezji i niskiego sprzężenia – złotego standardu projektowania.

Dlaczego to ważne?

Cecha systemuNiskie sprzężenieWysoka kohezja
Testowalność✅ Łatwa✅ Łatwa
Rozszerzalność✅ Modułowa✅ Przewidywalna
Refaktoryzacja✅ Bezpieczna✅ Czysta
Zrozumiałość kodu✅ Izolowana✅ Logiczna

Jak to osiągnąć?

✅ Stosuj wstrzykiwanie zależności
✅ Dziel kod zgodnie z zasadą jednej odpowiedzialności (SRP)
✅ Używaj wzorców projektowych (np. Strategy, Adapter)
✅ Grupuj klasy zgodnie z kontekstem domeny (np. DDD)
✅ Refaktoruj, gdy widzisz "kuchnię z tysiącem zadań"

Podsumowanie

  • Coupling to pytanie: jak bardzo zależysz od innych?

  • Cohesion to pytanie: czy robisz jedną rzecz dobrze, czy wszystko po trochu?

Dążymy do niskiego sprzężenia i wysokiej kohezji – to podstawa dobrze zaprojektowanych, testowalnych i skalowalnych systemów.

wtorek, 8 października 2024

dev{tools}: - Coding Rules znaczenie zasad kodowania w zespole

    Zasady kodowania (coding rules) to nieodłączny element efektywnej współpracy w zespołach programistycznych. Spójne zasady pomagają w utrzymaniu czytelności, spójności i jakości kodu, niezależnie od tego, ilu programistów nad nim pracuje. W tym artykule przyjrzymy się, jak wspólne zasady kodowania wpływają na efektywność zespołów, ułatwiają procesy przeglądów kodu (PR) i podnoszą poziom wytwarzanego oprogramowania.



Dlaczego zasady kodowania są kluczowe?

  1. Spójność kodu: Każdy programista może pisać kod w inny sposób. Wprowadzenie wspólnych zasad kodowania eliminuje te różnice, co sprawia, że kod jest jednolity i łatwiejszy do zrozumienia.
  2. Lepsza jakość kodu: Dobrze ustalone zasady kodowania pomagają unikać typowych błędów, takich jak nieczytelne nazewnictwo, brak komentarzy czy niewłaściwa struktura plików.
  3. Szybsze przeglądy kodu (PR): Zasady kodowania eliminują drobne niezgodności, co pozwala skupić się na istotnych kwestiach podczas code review, jak wydajność i poprawność logiki.
  4. Podniesienie poziomu produktu: Spójne zasady kodowania pomagają tworzyć bardziej czytelny, niezawodny i łatwiejszy do utrzymania kod, co bezpośrednio przekłada się na wyższą jakość końcowego produktu.

Przykłady zasad kodowania

Przyjrzyjmy się kilku przykładom zasad kodowania w trzech popularnych językach programowania: Java, C# i PHP. Zasady te są zgodne z oficjalnymi wytycznymi dla każdego z języków.

Java Coding Rules (zgodnie z Google Java Style Guide)

  • Nazewnictwo klas i metod: Klasy powinny być nazwane w stylu PascalCase (np. MyClass), a metody w stylu camelCase (np. myMethod()).

  • Unikaj używania magicznych liczb: Używanie „magic numbers” w kodzie może utrudniać jego zrozumienie. Zaleca się definiowanie stałych o opisowych nazwach zamiast używania twardo zakodowanych liczb:


    public static final int MAX_USERS = 100;
  • Komentarze w kodzie: Każda publiczna klasa i metoda powinna mieć komentarz opisujący jej funkcję:


    /** * Oblicza sumę dwóch liczb. */ public int add(int a, int b) { return a + b; }

Oficjalny przewodnik Google dotyczący stylu kodowania Java: Google Java Style Guide.

C# Coding Rules (zgodnie z Microsoft C# Coding Conventions)

  • Nazewnictwo właściwości i metod: W C# właściwości, klasy i metody powinny być nazwane w stylu PascalCase (np. MyMethod), a zmienne lokalne i prywatne pola w stylu camelCase (np. myVariable).

  • Używaj interpolacji ciągów znaków: W C# zaleca się stosowanie interpolacji ciągów znaków, ponieważ zwiększa to czytelność kodu:


    string name = "John"; string message = $"Hello, {name}!";
  • Obsługa wyjątków: Bloki try-catch muszą zawierać wyraźnie opisane wyjątki oraz odpowiednie działania naprawcze:


    try { // kod } catch (Exception ex) { Console.WriteLine(ex.Message); }

Oficjalny przewodnik Microsoft dotyczący konwencji kodowania C#: Microsoft C# Coding Conventions.

PHP Coding Rules (zgodnie z PHP-FIG PSR-12)

  • Nazewnictwo klas i metod: Klasy powinny być nazwane w stylu PascalCase (np. MyClass), a metody w stylu camelCase (np. myMethod()).

  • Deklaracja typów w funkcjach: Zaleca się deklarowanie typów argumentów i zwracanych wartości w funkcjach:


    function sum(int $a, int $b): int { return $a + $b; }
  • Skrócona forma tablic: Należy używać nowoczesnej, skróconej formy tablic:


    $array = [1, 2, 3];

Oficjalny przewodnik PSR-12 dotyczący standardów kodowania w PHP: PHP-FIG PSR-12.

Przechowywanie zasad kodowania w repozytorium

    Zasady kodowania najlepiej przechowywać bezpośrednio w repozytorium projektu, aby były łatwo dostępne dla wszystkich członków zespołu. Możesz umieścić je w pliku CONTRIBUTING.md, który będzie zawierał opis praktyk i reguł obowiązujących w projekcie. Dodatkowo, można skonfigurować lintery i formattery (np. ESLint, Prettier), które automatycznie wymuszą przestrzeganie zasad kodowania przy każdym commitcie.

Jak wdrożyć zasady kodowania w zespole?

  1. Określ zestaw zasad: Na początek, zespół powinien wspólnie ustalić podstawowy zestaw zasad kodowania. Mogą to być zasady związane z formatowaniem, strukturą kodu czy standardami nazewnictwa.
  2. Dokumentuj zasady: Upewnij się, że wszystkie zasady są dobrze udokumentowane i dostępne dla całego zespołu, najlepiej bezpośrednio w repozytorium projektu.
  3. Używaj narzędzi automatyzujących: Wdrażaj narzędzia, które automatycznie sprawdzają zgodność kodu z ustalonymi zasadami, jak lintery, formattery czy automatyczne testy.
  4. Monitoruj i aktualizuj zasady: Zasady kodowania powinny być regularnie przeglądane i aktualizowane w zależności od potrzeb zespołu i ewolucji projektu.

Podsumowanie

Wprowadzenie zasad kodowania w zespole programistycznym poprawia spójność i jakość kodu, przyspiesza przeglądy kodu oraz podnosi poziom końcowego produktu. Dostosowanie zasad do konkretnego języka, jak Java, C# czy PHP, oraz automatyzacja ich egzekwowania za pomocą narzędzi, to krok w stronę bardziej efektywnej pracy zespołowej i lepszego oprogramowania.

piątek, 30 sierpnia 2024

Polecenia Git, które warto znać

 Git jest podstawowym narzędziem dla programistów, ale większość używa jedynie podstawowych poleceń. Warto jednak poznać nowoczesne komendy, które ułatwiają pracę:

  • git switch: Przełączanie między gałęziami, bez ryzyka utraty zmian.
  • git restore: Przywracanie plików do ostatniej zatwierdzonej wersji.
  • git sparse-checkout: Praca z wybranymi katalogami w dużych repozytoriach.
  • git worktree: Praca na wielu gałęziach jednocześnie.

Więcej informacji znajdziesz tutaj.

czwartek, 28 marca 2024

Nie tylko technologie



Kto powiedział, że od takich autorytetów jak Martin Fowler i Uncle Bob Martin  dowiem się wyłącznie o poprawnej architekturze, dobrych praktykach programowania i innych technicznych kwestiach? Na X natknąłem się na ich dyskusję na temat używania mediów społecznościowych. Dzięki temu odkryłem nostr– otwarty protokół, który umożliwia tworzenie globalnych, zdecentralizowanych i wolnych od cenzury platform mediów społecznościowych. Teraz eksploruję, poznaję i będę testował...


wtorek, 6 czerwca 2023

What is code refactoring?




Refaktoryzacja kodu to proces wprowadzania zmian w projekcie/programie, w wyniku których nie zmienia się funkcjonalność, lecz utrzymuje się odpowiednią, wysoką jakość organizacji systemu. Celem refaktoryzacji jest poprawa kodu i jego struktury, a nie wytwarzanie nowej funkcjonalności.

Oczekiwane korzyści z refaktoryzacji

Refaktoryzacja ma na celu rozwiązanie konkretnych problemów i przyniesienie korzyści, takich jak:

  • Łatwiejsza rozbudowa systemu
  • Lepsza współpraca programistów
  • Mniej czasu na dyskusje, więcej czasu na dobre rozwiązania
  • Łatwiejsze wdrażanie zmian
  • Mniej błędów
  • Mniejsze wydatki na wsparcie i rozwój w przyszłości

Lista korzyści jest długa i nieograniczona. Przed przystąpieniem do refaktoryzacji ważne jest określenie celu, jaki chcemy osiągnąć.

Daily Refactoring - codzienne ulepszanie kodu

Podstawowym krokiem do utrzymania dobrze zorganizowanego kodu jest codzienne refaktoryzowanie. Zgodnie z koncepcją Test-Driven Development (TDD), cykl wytwarzania kodu składa się z trzech kroków: red (tworzenie testów jednostkowych, które nie przechodzą), green (implementacja kodu produkcyjnego, który pozwala na przejście testów) oraz refactor (poprawa kodu w celu jego ulepszenia).

Codzienne refaktoryzowanie charakteryzuje się tym, że:

  • Funkcjonalność jest pokryta przez testy
  • Większość zadań refaktoryzacyjnych może być wykonana automatycznie przez środowisko programistyczne (IDE)
  • Nie wymaga dużego nakładu czasu

Przykłady metod stosowanych w codziennym refaktoryzowaniu to m.in. zmiana nazwy (Rename), zmiana sygnatury (Change Signature), wyodrębnianie metod (Extract Method), wstawianie kodu inline (Inline method), wprowadzanie stałych (Introduce Constant), wprowadzanie pól (Introduce Field), wprowadzanie parametrów (Introduce Parameter), wprowadzanie zmiennych (Introduce Variable) oraz bezpieczne usuwanie (Safe Delete).

Strategic Refactoring - zmiany na większą skalę

Kolejnym krokiem jest refaktoryzacja strategiczna, która dotyczy większych zmian w systemie, takich jak modyfikacja większej liczby klas, modyfikacja całego modułu lub nawet wydzielenie osobnego mikroserwisu.

W refaktoryzacji strategicznej rozważane są zmiany, które mają na celu dostosowanie kodu do nowych wymagań biznesowych lub technologicznych. Przykłady takich zmian to migracja do nowoczesnych frameworków lub języków, zmiana architektury systemu, wprowadzenie wzorców projektowych, rozdzielenie odpowiedzialności między klasy lub moduły oraz usunięcie zbędnego lub przestarzałego kodu.

Refaktoryzacja strategiczna wymaga więcej czasu i planowania, ale przynosi większe korzyści w dłuższej perspektywie. Jest częścią zarządzania projektem informatycznym.




Podsumowanie

Refaktoryzacja kodu jest ważnym elementem tworzenia oprogramowania, który pozwala utrzymać aplikacje w dobrej kondycji i umożliwia ich rozwój. Codzienne refaktoryzowanie oraz refaktoryzacja strategiczna są dwa rodzaje refaktoryzacji, które mają swoje miejsce w procesie tworzenia oprogramowania. Ważne jest, aby regularnie i systematycznie wykonywać codzienne refaktoryzowanie, a także planować i przeprowadzać refaktoryzację strategiczną w celu dostosowania kodu do nowych wymagań.

Pamiętajmy, że refaktoryzacja ma na celu poprawę jakości kodu i organizacji systemu, co przekłada się na efektywność i łatwiejsze rozwijanie aplikacji. Przed przystąpieniem do refaktoryzacji warto określić oczekiwane korzyści i realistyczny zakres czasowy dla ich osiągnięcia.