Prawidłowe zastosowanie komentarzy jest kompensowaniem naszych błędów przy tworzeniu kodu. (…) Obecność komentarzy zawsze sygnalizuje nieporadność programisty. Musimy z nich korzystać, ponieważ nie zawsze wiemy jak wyrazić nasze intencje bez ich użycia, ale ich obecność nie jest powodem do świętowania.
Robert C. Martin – Czysty kod
Krótki cytat z jednej najbardziej popularnych książek traktujących o praktykach tworzenia dobrego oprogramowania, w dużym stopniu odzwierciedla problem jakim jest przeładowanie kodu komentarzami. Wykorzystujemy je aby uzasadnić pewnego rodzaju lenistwo, brak czasu, albo po prostu chęć pisania dużej ilości kodu, która w ostateczności okazuje się złudnym sukcesem.
// Checking if the employee should get the bonus
if ($employee->age > 65 && $employee->status === 'active') {}
Code language: PHP (php)
if ($employee->isEligibleForBonus()) {}
Code language: PHP (php)
Analizując powyższy przykład, możemy zauważyć, że kod wyglada zdecydowanie schludniej jeśli zamiast niejasnego warunku wykorzystamy czytelną funkcję, której sama nazwa zniweluje potrzebę tłumaczenia o co chodzi.
Błędne Komentarze
Paplanina
Nie wyjaśniaj rzeczy, które są już jasne.
Niepoprawnie
/**
* @var Product Product object;
*/
private Product $product;
/**
* Function returns the price that is loaded from the product object bla bla bla.
*/
public function getProductPrice() {
return $this->product->getPrice();
}
Code language: PHP (php)
Poprawnie
private Product $product;
public function getProductPrice(): int {
return $this->product->getPrice();
}
Code language: PHP (php)
Doc Blocks
Nie umieszczaj niepotrzebnych informacji w komentarzach blokowych.
Poniższy przykład kalkuluje finalną cenę, która jest wynikiem mnożenia buforu oraz wskaźnika ryzyka. Ale co dokładnie jest źle?
Niepoprawnie
/**
* Function returns the final price.
* @param int $a Total price.
* @param int $b Buffer miltiplier.
* @param int $c Risk miltiplier.
* @return int Final price.
*/
public function getPrice($a, $b, $c) {
return $a * $b * $c;
}
Code language: PHP (php)
1. Należy wyjaśnić znaczenie argumentów funkcji, ponieważ są domyślnie niezrozumiałe.
2. Nazwa funkcji informuje o tym, że zwracana jest *jakaś* cena, a dokładne wyjaśnienie czym ona jest znajduje się w komentarzu.
3. Informujemy o typach komentarzu blokowym mając możliwość wykorzystania typów argumentów.
Poprawnie
public function getFinalPrice(int $totalPrice, int $bufferMultiplier, int $riskMultiplier): int {
return $totalPrice * $bufferMultiplier * $riskMultiplier;
}
Code language: PHP (php)
1. Poprawne nazewnictwo argumentów jednoznacznie wyjaśniło ich znaczenie.
2. Dokładna nazwa funkcji zniwelowała potrzebę wyjaśnienia działania poprzez komentarz.
3. Wykorzystanie typów również wyeliminowało potrzebę pozostawienia komentarza.
Punkt 3 zależy od projektu, ale wymaganie te musi być spełnione jeśli mamy możliwość pracy z językiem wspierającym typy i nie przejmujemy się systemami automatycznie generującymi dokumentacje.
Author
Nie informuj o autorze w komentarzu blokowym.
Niepoprawnie
/**
* @author PH
*/
class Product {
/**
* @author PH
*/
public function getPrice() {}
/**
* @author PH
*/
public function getName() {}
}
Code language: PHP (php)
Poprawnie
class Product {
public function getPrice() {}
public function getName() {}
}
Code language: PHP (php)
Jak w takim wypadku poznać autora?
1. Wykorzystaj GitLens – https://marketplace.visualstudio.com/items?itemName=eamodio.gitlens
2. Wykorzystaj git blame – https://gitbetter.substack.com/p/how-to-use-git-blame-effectively.
3. Wykorzystaj github.com / bitbucket.com aby sprawdzić kto edytował plik.
Notatki
Nie pozostawiaj w kodzie niepotrzebnych adnotacji.
// Done by Andrew
$test = '';
Code language: PHP (php)
Kod
Nie pozostawiaj niepotrzebnego kodu.
// public function getPrice($a, $b, $c) {
// return $a * $b * $c;
// }
Code language: JSON / JSON with Comments (json)
Komentarze akceptowalne
TODO
Czasami dobrym pomysłem jest umieszczenie komentarzy @todo
w celu poinformowania o zamierzeniach, albo ważnych elementach, które zostaną zmienione w przyszłości.
/**
* @todo Remove when XY will be ready.
*/
Code language: PHP (php)
Konsekwencje
Jeśli kod tego wymaga, umieść informacje o konsekwencjach w celu ostrzeżenia innego dewelopera.
/**
* This function will burn your machine.
*/
public function importData(): void {}
Code language: PHP (php)
Wyjaśnienia
Jeśli sytuacja tego wymaga – np. przez brak budżetu – umieść komentarz wyjaśniający istnienie danego rozwiązania.
/**
* Function fixes the problem with FacetWP and Postfinance plugin.
*
* Symptoms: The FacetWP plugin doesn’t work correctly when the Access plugin is also active. For example, if you add a custom
* search and try to filter by taxonomy, the FacetWP filter is ignored and a full list of posts is rendered. The issue
* is actually caused by the FacetWP plugin, which is running the init filter before everything else.
*
* If you use FacetWP while Access is active basically all FacetWP’s AJAX-based features like search results and pagination will fail.
*
* Workaround: FacetWP modifies the Main Query with additional parameters and runs another WP_Query instance to show search results.
* Here is a short explanation of what happens:
*
* - When Toolset Access tries to check/set permissions for the Custom Post Types, it runs the toolset_access_get_current_page_id
* function that, in turn, runs the url_to_postid WordPress core function.
* - That url_to_postid function runs another WP_Query that replaces the result from the FacetWP’s query and completely breaks the
* results from FacetWP.
*
* This happens because of the late priority of Access and the early priority of FacetWP.
*
* Fix: Theme tells the plugin that the payment page is the one with `woo_postfinancecw` slug.
*
* @filter woocommerce_postfinancecw_is_plugin_page
* @see https://toolset.com/errata/compatibility-issue-between-facetwp-and-access-plugins/
*/
public function fixFilters(): bool
{
global $wp;
return 'woo_postfinancecw' === $wp->request;
}
Code language: PHP (php)
Nie znaczy to, że powinieneś umieszczać takie komentarze w każdym jednym miejscu w kodzie, które wydaje się skomplikowane. Zawsze powinieneś podchodzić do tego tematu ostrożnie wcześnie potwierdzając, że nie zostaje Ci nic innego.
Kilka reguł wystarczy, aby znacznie odchodzić kod. Najważniejsze w tym wszystkim jest to, aby rozumnie podchodzić do wykorzystania komentarzy.
Za każdym razem gdy napisałeś komentarz, przeczytaj go jeszcze raz krok po kroku czytając również kod. W wielu przypadkach w tym tekście wyłonią się od razu nazwy funkcji, na które z pewnością można rozbić skomentowaną funkcję.
Dodaj komentarz