Czysty kod - funkcje z jedną operacją, rodzice, polimorfizm zamiast switch

0

Witam,
czytam książkę Czysty Kod - podręcznik dobrego programisty i mam kilka pytań do zaawansowanych programistów.

  1. Rzeczywiście piszecie funkcje z jedną operacją? Tam jest przykład:
public void pay() {
   for (Employee e : employees) {
      if (e.isPayday()) {
         Money pay = e.calculatePay();
         e.deliverPay(pay);
      }
   }
}

I według tej książki powinno być:

public void pay() {
   for (Employee e : employees)
   payIfNecessary(e);
}
private void payIfNecessary(Employee e) {
   if (e.isPayday())
   calculateAndDeliverPay(e);
}
private void calculateAndDeliverPay(Employee e) {
   Money pay = e.calculatePay();
   e.deliverPay(pay);
}

Rzeczywiście w dużych firmach tak piszecie kod?

  1. Odwoływanie się do rodziców/dzieci itp
    Nie mogę teraz przykładu znaleźć ale chodziło o coś takiego:
object.getA().getB().getC();

Żeby tego unikać, więc jak to robić? W klasie A zaimplementować to przejście do C czy o co właściwie chodzi? Czy w ogóle nie projektować systemów, które mają takie połączenia?

  1. Zamiast instrukcji switch stosować polimorfizm. Tutaj niestety nie było przykładu chociaż 2 razy o tym było w książce. O co tu może chodzić?
2
  1. Są 10 grupy programistów, Ci którzy są ślepymi wyzwanwami "Clean Code" i pozostali. Dobre nazywane metod jest super, metody jednolinijkowe się zdarzają, ale żeby na siłę pakować wszystko w jedną linijkę to raczej odpada. Więc odpowiadając na Twoje pytanie: zależy czyj kod czytasz, jeśli zatwardziałego wyznawcy clean code wtedy będziesz miał sporo takich metod. Pisze się "i tak, i tak", jak zwykle wszystko zależy od konkretnego przypadku. Sam klasyfikuję siebie do "pozostałych", chociaż jednolinijkowe metody też czasami piszę.

  2. Zazwyczaj w klasie A opakowujesz getB a w klasie B getC. Wtedy a.getSomething() zwraca b.getSomething() itd. Generalnie jeśli tworzy się taki tasiemiec to można tutaj szukać lepszego rozwiązania. Jeśli w obiekcie "na górze" ptrzebujesz dostępu do tak "głębokich" detali, można zstanowić się nad uproszczeniem.

  3. Chodzi prawdopodobnie o zastosowanie mechanizmu podobnego to tego w kodzie poniżej:

public interface Something {
    void someMethod();
}
   
class A implements Something {}
class B implements Something {}

Map<String, Something> mapWithSomething = new HashMap<>;
mapWithSomething.put("x", new A());
mapWithSomething.put("y", new B());

mapWithSomething.get("x").someMethod()
0

Dzięki za odpowiedź, a jakie jeszcze książki albo tutoriale o czystym kodzie polecacie?

1

Uncle Bob napisał kontynuację tego tytułu. Jako, że "Clean Code" dobrze się sprzedawał napisał "Clean Coder". Sam tej książki nie czytałem więc nie mogę Ci powiedzieć czy jest ok, ale jako "kontynuacja" może Cię zainteresować.

1
samouczek napisał(a):

Uncle Bob napisał kontynuację tego tytułu. Jako, że "Clean Code" dobrze się sprzedawał napisał "Clean Coder". Sam tej książki nie czytałem więc nie mogę Ci powiedzieć czy jest ok, ale jako "kontynuacja" może Cię zainteresować.

"Clean Coder" opisuje bardziej to jak profesjonalnie pracować niż jak programować.

0
samouczek napisał(a):
  1. Są 10 grupy programistów, Ci którzy są ślepymi wyzwanwami "Clean Code" i pozostali.

To bardzo ciekawe... A gdzie się ukrywają ci wszyscy fanatycy Clean Code?
Ja raczej zauważyłem, że ludzie albo się starają i piszą kod rozsądnie (czasami metoda ma jedną linijkę, czasami 5, a czasami 20), albo mają jakość kodu gdzieś i piszą metody na setki linii. Niestety, tych drugich jest znacznie więcej.

1

A odpowiadając na temat wątku,

  1. tak, staram się tak pisać. Ale nie jestem fanatykiem i to zależy od kontekstu.
    Np. scenariusze testowe raczej wolę napisać jako jedną funkcję z wysokopoziomowymi wywołaniami API (typu "daj transakcję nr").

Hipotetyczne


public void pay() {
   for (Employee e : employees) {
      if (e.isPayday()) {
         Money pay = e.calculatePay();
         e.deliverPay(pay);
      }
   }
}

zamieniłbym na:

public void pay() {
   for (Employee e : employees) {
      e.payIfPayDay();
   }
}

lub

public void pay() {
  employees.stream().forEach(Employee::payIfPayDay);
}

Jeśli chodzi o fanatyzm to zwykle oznacza on brak komunikacji, więc w pracy nie jest dobry.

  1. object.getA().getB().getC();

Powinno się tego unikać, ale mam wyjątki, np w GUI.

panel.color.setValue(a);

3- czy 4-poziomowe wywołanie oznacza że grzebiesz gdzieś w bebechach silnika zamiast pojechać do autoryzowanego serwisu.
W wyjątkowych sytuacjach może to być niezbędne, ale nie powinno być regułą (chyba że pracujesz w supporcie i Twoja zmiana będzie na pewno refaktorowana).

  1. switch jest elegancki, ale w aplikacjach biznesowych mało go widzę. Też nie trzymałbym się sztywno tej zasady.

1 użytkowników online, w tym zalogowanych: 0, gości: 1