Clean Code: Digest (Capítol 4: Comentaris)

Àngel Fernández
Calidae Blog
Published in
7 min readOct 3, 2016
‘Hello World’ en Brainfuck

L’ús de comentaris acostuma a mostrar el nostre fracàs a l’hora d’expressar-nos en codi. Els hem de fer servir perquè a vegades és impossible explicar-ho tot simplement amb codi, però no són motiu de celebració.

A més a més, els comentaris poden mentir. El codi canvia i evoluciona. I tot sovint els comentaris no ho fan al mateix ritme. Si no refactoritzem els comentaris, acabaran mentint sobre el que expliquen, i creen més confusió al lector que si simplement no existissin:

if (!is_null($concept)) { //Inner join to get translation
$sql .=" LEFT JOIN traducciones td_cc_permalink ON ...

Els comentaris no compensen mal codi

La motivació principal d’escriure comentaris és maquillar el mal codi. Creem un codi confús i desorganitzat i decidim escriure comentaris per explicar-lo.
Codi net i expressiu amb pocs comentaris és de lluny millor que codi desendreçat i complexe amb un munt de comentaris.

Explica’t en codi

Hi ha cops on és difícil escriure un bloc de codi auto-explicatiu. Per exemple, podeu veure la següent expressió:

if (Cache::has('flights-'.$this->hash)) { // Encara tenim sessió
...

Sembla que sense aquest comentari, la condició no s’entendria. Però és una assumpció falsa, ja que realment el podem reescriure:

if (Cache::isFligthSessionActive()) {
...

Abstraure i encapsular el codi seguint les regles top-down ens ajuda a explicar-nos en codi i poder prescindir de comentaris. Es un bon moment per rellegir el capítol de funcions ;)

Bons comentaris

L’únic bon comentari és el que no trobes la manera d’escriure en codi.

  • Comentaris legals: Típics comentaris clarificant la llicencia, com els de GPL o similars.
  • Comentaris informatius: Per exemple, podries explicar de forma amigable quin format espera una expressió regular amb un comentari. Això sí, sempre que hagis respectat la regla top-down i per tant l’expressió regular i el comentari estiguin encapsulades en una funció de baix nivell amb un nom auto-explicatiu.
  • Explicació de la intenció: A vegades un comentari ens dóna informació sobre la implementació i la intenció de la decisió. Si pots implementar una cosa de varies formes vàlides, un comentari t’ajudarà a explicar perquè t’has decidit per una forma en concret.
  • Clarificació: A vegades un comentari ens pot ajudar a clarificar un tros de codi embolicat. A vegades no el pots reescriure o encapsular perquè pertany a una llibreria externa o simplement no el pots modificar. En aquests casos un comentari clarificador de què fa pot ser molt útil.
  • Avis de conseqüències: Pot ser útil avisar a altres desenvolupadors sobre certes conseqüències. Per exemple, pots tenir comentat un test a la teva bateria de testos unitaris perquè triga molt i no el vols passar sempre. Avisar amb un comentari de les conseqüències de descomentar-lo (quant temps pot trigar aproximadament, etc.) és una gran ajuda.
  • Comentaris TODO, FIXME, etc.
  • Amplificació: Comentaris per donar importància a un bloc de codi, per ressaltar-lo quan podria semblar insubstancial i és realment important per la implementació.
  • Javadocs en APIs públiques: Si escrius una API pública, has d’escriure una bona documentació sobre aquesta. I qui diu Javadoc, diu PHPDoc o qualsevol altre cosa similar.

Si un comentari no encaixa en cap d’aquestes descripcions, probablement és un mal comentari.

Xiuxiueig

Escriure un comentari només perquè et dona la sensació de que ha de ser-hi o que el procés o requereix, és un hack. Si escrius un comentari, gasta el temps necessari per assegurar-te que és el millor comentari que pots escriure.

foreach ($this->conn->fetchAll($sql) as $val) { //Only one result
...

En aquest exemple, que ens està dient el comentari? El fetchAll només tindrà un resultat? I perquè el recorrem amb un for, doncs? Per result s’està referint a una altre cosa?
En un cas així l’únic recurs que tenim es llegir tot el context del codi per entendre el bucle i el comentari que l’acompanya.

Comentaris enganyosos

A vegades, tot i tenir les millors intencions, els desenvolupadors escrivim una sentencia en els nostres comentaris no suficientment precisa per ser exacte. Això genera desinformació, i pot induir a errors de comprensió.

//Get language
$lang = $this->api->db->getLangs($this->urldata['lang']);

Per exemple, llegint en diagonal aquest codi, gràcies al comentari i al nom de la variable, pensaríem que a $lang hi ha un idioma. La realitat és que el comentari ens està enganyant, ja que si llegim bé, la funció torna una llista d’idiomes, i no un sol. Aquest cas és especialment dramàtic perquè el nom la variable també ens està enganyant, i més endavant al codi es fa servir aquesta variable amb un espectacular $lang[0].

Comentaris de diari

A vegades hi ha gent que afegeix un comentari al principi d’un mòdul cada cop que l’edita. Com si fos un diari, un log de canvis.
Avui en dia, amb els sistemes de control de versions, això ja no té cap sentit.

Comentaris redundants

Quan un comentari no és més informatiu que el propi codi, és un despropòsit. A més, molts cops el comentari és més feixuc de llegir que el propi codi.

// It will check the data
$this->api->validateData($required, $this->urldata, $strMsg);

Comentaris obligatoris

A vegades seguim regles autoimposades com que tota funció ha de tenir un javadoc, o cada variable ha de tenir un comentari explicant-la. I això ens porta a comentaris redundants, que escrivim simplement per obligació.

/**
* Function to manage the GET action.
*/
public function getAction(){
...

Comentaris sorollosos

Comentaris que no són res més que soroll. Són redundants, però de forma exagerada. Un parell d’exemples del llibre:

private int dayOfMonth; // The day of month./** The name. */
private String name;

El problema d’aquests comentaris és que, si n’hi ha, acostumen a haver-n’hi molts. I fan que els acabem ignorant al llegir o refactoritzar el codi. Acaben passant coses com que els ignorem al copiar codi i…

//Get expedient extras and it's rates
public function getExpedientExtras($id_exp) { ...
//Get expedient extras and it's rates
public function getExpedientIncidents($id_exp){ ...

No utilitzis un comentari quan pots fer servir una funció o variable

Ja ho hem dit al principi, però recordem-ho. Torna a dalt, llegeix la secció ‘Explica’t en codi’, i llavors torna aquí i continua llegint :)

Marcadors de posició

A vegades als desenvolupadors ens agrada marcar una posició en un fitxer de codi, com per exemple:

//////////////////////////////////////////////////////////////
// ProductsInfoController FUNCTIONS
//////////////////////////////////////////////////////////////

Hi ha poques vegades on un banner com aquest pot tenir sentit. La majoria de cops simplement és un separador, i probablement en comptes d’un separador necessites una millor organització de fitxers. Un banner pot ser alarmant si no veus banners molt sovint. Però si s’utilitzen de forma comú, perden el seu significat, i acaben convertint-se en soroll de fons.

Comentaris de tancament de bloc

Alguns desenvolupadors posen comentaris per especificar el final d’un bloc de codi.

for (...){
if (...) {
...
} // fi if
} // fi for

Normalment això es troba necessari quan son funcions llargues. La solució no es posar el comentari, la solució és escriure funcions curtes ;)

Atribucions i Bylines

(...) // byAngel

Pots pensar que serà útil i que així qui ho lleigeixi sabrà a qui preguntar si té algun dubte, però el cert és que amb els anys el comentari perdrà rellevància i es convertirà en soroll.

De nou, els sistemes de control de versions son perfectes per recordar informació sobre qui o quan es va escriure codi.

Codi comentat

Poques pràctiques son tan odioses com comentar codi antic. No ho facis! El següent desenvolupador que vingui i vegi codi comentat, no s’atrevirà a esborrar-lo pensant que si està allà és per alguna raó.

Sabeu qui guarda el codi antic? He de tornar a anomenar el concepte de control de versions? Esborra el codi antic, va. No es perdrà. T’ho prometo.

Comentaris HTML

L’HTML en els comentaris de codi és una abominació. El principal ús dels comentaris és llegir-los al mateix editor o IDE, no que surtin macos en una eina web de documentació.

/**
* Function to check if Reseller has access to an expedient.
*
* @param array $id_exp <br />
* <i>Expedient identification.</i>
* @return boolean
*/

Informació no local

Quan escrius un comentari, ha de descriure el codi que apareix a prop. L’exemple que ens posa el llibre és aquest:

/**
* Port on which fitnesse would run. Defaults to 8082.
*/
public void setFitnessePort(int fitnessePort) {
...

La informació sobre el port per defecte no ajuda a descriure la funció, i a més aquesta funció no té cap control sobre el port per defecte, està parlant sobre una altre part del sistema. No hi ha garantia de que si canvia el port oficial algú recordi venir a canviar aquest comentari.

Capçaleres de funcions

Una funció curta no necessita massa descripció. Un nom ben escollit per a una funció petita que fa una sola cosa sempre serà millor que un comentari a la capçalera.

Déu n’hi do, una cosa a priori tan simple com els comentaris dóna per un article en si mateix!

En el pròxim article resumiré el que diu el llibre sobre com formatar el nostre codi font. I mentrestant, si voleu seguir llegint podeu tornar a:

--

--