1. Code
  2. Coding Fundamentals

Uso de CodeSniffer PHP con WordPress: comprensión de los olores de código

Scroll to top

Spanish (Español) translation by Elías Nicolás (you can also view the original English article)

A menudo, la forma en que escribimos el código depende de cómo empezamos con la programación.

Por ejemplo, si alguien tiene una educación formal en computación, es probable que conozcan una variedad de principios que les impiden escribir código de mala calidad. Esto no es una regla, por supuesto, sino una observación.

Del mismo modo, aquellos que llegan a la programación por su cuenta, fuera de un entorno formal, a menudo terminan por enseñarse a sí mismos y aprender de una variedad de recursos diferentes. A veces, esto puede causar problemas con el tipo de código que está escrito.

Para ser absolutamente claro: No estoy diciendo que una educación formal en computación triunfa por sobre alguien que se enseña a sí mismos, ni viceversa. Algunos programadores fantásticos son aquellos que son educados; Otros son los que son autodidactas. Pero lo único que ambos tienen en común con los demás es que no están exentos de escribir olores de código de vez en cuando.

En este artículo, vamos a tomar una mirada introductoria a los olores de código. Vamos a examinar lo que son, lo que parecen, y cómo se manifiestan a menudo en el trabajo que hacemos. Usaremos PHP para nuestros ejemplos.

En la segunda parte de esta serie, vamos a echar un vistazo a cómo podemos evitar escribir olores de código. En concreto, utilizaremos PHP, un par de herramientas y WordPress como el entorno de elección.

Pero primero, vamos a tener una introducción a los olores de código.

¿Qué son los olores de código?

Dependiendo del tipo de desarrollador quien usted pregunte, probablemente obtendrá una variación en la siguiente definición:

Olor de Código, también conocido como un mal olor, en el código de programación de equipo, se refiere a cualquier síntoma en el código fuente de un programa que posiblemente indica un problema más profundo.

Esta definición es directamente de Wikipedia. No está mal, pero no es mi favorita en el tema. En cambio, mi definición favorita viene de un prolífico y popular programador llamado Martin Fowler. Usted puede leer su opinión entera sobre el tema de los olores del código en este artículo, pero lo he sacado los puntos siguientes:

  1. "Un largo método es un buen ejemplo de esto - sólo mirando el código y mi nariz se contrae si veo más de una docena de líneas de Java".
  2. "Los olores no son inherentemente malos por sí solos - a menudo son un indicador de un problema en lugar del problema en sí."
  3. "Las clases de datos (clases con todos los datos y sin comportamiento) son buenos ejemplos".

Si no ha leído el artículo, termina con esto:

Una de las cosas buenas de los olores es que es fácil para las personas inexpertas detectarlas, incluso si no saben lo suficiente como para evaluar si hay un problema real o para corregirlas.

Y creo que es una declaración fantástica porque significa que este tema se posiciona perfectamente para aquellos que son programadores, pero no están seguros de dónde comenzar cuando se trata de identificar y tratar los olores de código.

En resumen, la experiencia no juega un papel importante en esto. Claro, los que son más experimentados son más propensos a identificar los olores (porque han visto más de ellos), pero los desarrolladores menos experimentados deben ser capaces de identificarlos.

¿Tienes ejemplos?

Por supuesto, cuando se trata de un tema como olores de codigo, a menudo es más fácil hablar de ellos en un nivel abstracto que es realmente hacer algo al respecto. Pero eso no es práctico, ni es aplicable a nuestro trabajo cotidiano.

Dicho esto, ¿por qué no echar un vistazo a algún ejemplo de olores de código? Vamos a examinar por qué son problemáticos y, a continuación, ofrecer una solución para la forma en que el olor se puede eliminar mediante la refactorización del código.

Ejemplo 1: Convenciones de nombres claras

Uno de los olores de código más fáciles de detectar es cuando un programador ha optado por utilizar nombres de variables poco claras. Es decir, en el contexto del código, no está claro qué se supone que representa una variable dada.

Claro, hay momentos en que esto es aceptable (como usar un i en un bucle for). Pero en un método más largo, no es exactamente lo mismo que el bucle for).

Por ejemplo:

1
<?php 
2
public function get_things( $x ) {
3
4
  $l = array();
5
6
  for ( $i = 0; $i < count( $x ); $i++ ) {
7
8
    if ( true === $x[ $i ] ) {
9
      array_push( $l, $x[ $i ] );
10
    }
11
12
  }
13
14
  return $l;
15
16
}

Dado el tiempo suficiente, es probable que sea capaz de averiguar lo que está haciendo. En primer lugar, es un método relativamente simple. En segundo lugar, podríamos leer las variables, bloques y valores return para obtener una mejor idea de lo que está sucediendo.

Pero si estamos buscando escribir código limpio que sea más fácil de entender a medida que nos referimos a él u otro programador trabaje con él, entonces usar convenciones de nombres claras siempre ayuda. Y el código anterior no utiliza convenciones de nomenclatura claras.

En su lugar, vamos a refactorizarlo para que se vea así:

1
<?php
2
3
public function get_flagged_items( $items ) {
4
5
  $flagged_items = array();
6
7
  for ( $i = 0; $i < count( $items ); $i++ ) {
8
9
    $current_item = $items[ $i ] ;
10
11
    if ( true === $current_item ) {
12
      array_push( $flagged_items, $current_item );
13
    }
14
  }
15
16
  return $flagged_items;
17
18
}

Mucho más fácil de entender, ¿no?

Observe que el algoritmo en sí no ha cambiado, pero el nombre de la función y los nombres de las variables tienen. Esto ha hecho que una gran diferencia en la lectura de este código. Si se le pregunta qué debe hacer este código, podemos decir algo como:

Devuelve un array de elementos marcados como verdadero desde un array predefinida de elementos.

En la medida de lo posible, evitar el uso de nombres de variables genéricas y utilizar lo que es la opción más clara para usted y sus compañeros.

Ejemplo 2: Manténgase NTR

En la programación, sería difícil encontrar un desarrollador que no había oído hablar de KISS o NTR (usted sabe, "No te repitas"). A pesar de esto, a menudo lo hacemos.

Esto es indicativo del hecho de que el intento de adherirse a los principios NTR de manera diferente con diferentes tipos de programadores. ¡Y eso está bien! No hay una sola manera de demostrar cómo adherirse a este principio.

Pero debido a que hay múltiples maneras de hacerlo, podemos proporcionar un ejemplo de lo que no debe verse y cómo debe ser.

Supongamos, para los propósitos del siguiente ejemplo, que tenemos una función llamada save_post y acepta dos argumentos: un ID postal y una cadena que representa el título de la publicación. Un olor de código sería algo como esto:

1
<?php
2
3
public function save_posts() {
4
5
  save_post( 1, 'Hello World!' );
6
  save_post( 2, 'Goodbye World!' );
7
  save_post( 3, 'What is this new world?' );
8
9
}

¿Pero por qué escriba manualmente una llamada a save_post tres veces? En su lugar, vamos a configurar un array asociativa, iterar a través de ella y, a continuación, llamar al método una vez por iteración.

1
<?php
2
3
public function save_posts() {
4
5
  $posts = [
6
    1 => 'Hello World!',
7
    2 => 'Goodbye World!',
8
    3 => 'What is this new world?',
9
  ];
10
11
  foreach ( $post as $post_id => $post_title ) {
12
    save_post( $post_id, $post_title );
13
  }
14
  
15
}

Aunque llamar al método una vez es bueno, el método se podría hacer aún más flexible al poder aceptar un array de mensajes como un argumento y dejar el bucle foreach intacto, aunque no es realmente el punto de este ejemplo.

Si te encuentras haciendo el mismo método, llama varias veces en una función pero con diferentes parámetros, puede que tengas olor de código. Y si lo hace, busque formas de refactorizarlo para que esté llamando al método una sola vez.

Después de todo, no quieres repetirte.

Ejemplo 3: Listas de parámetros largos

Una de las cosas más comunes que seguimos viendo en la programación, independientemente del idioma, es cuando una función acepta un gran número de parámetros.

Diferentes programadores tendrán opiniones sobre cuál es el número ideal de parámetros que una función debe aceptar, pero tienden a pensar que tres (dar o tomar dos, tal vez) es un buen número.

En primer lugar, echemos un vistazo a lo que una función con una larga lista de parámetros se vería como. Es probable que no haya sorpresas en el código siguiente, y es posible que se trate de algo exactamente como esto en uno de sus proyectos actuales:

1
<?php 
2
3
public function submit_order( $first, $last, $address1, $address2, $city, $state, $zip, $phone, $cc, $expiration ) {
4
5
  /* Attempt to submit the order. If the order is successful,

6
   * then return an instance of an Order object with the success status;

7
   * otherwise, return an instance of an Order object with the failed status 

8
   * and a message.

9
   */
10
  
11
}

Observe en el ejemplo anterior que no estamos preocupados por la implementación de la función. En cambio, estamos preocupados por el número de parámetros que requiere. Eso es una gran cantidad de información para enviar, y hará que el método de llamada sea mucho más feo, también.

Ni siquiera tiene éxito en el tema de la verificación y validación. Pero divago.

¿Cómo se puede limpiar esto? Personalmente, soy un fan de crear clases para representar colecciones de información como esta. Para este ejemplo en particular, podríamos tener una clase que presenta la información de contacto de una persona. Además, esa persona podría estar asociada con un número de tarjeta de crédito.

Los detalles de esto podrían reforzarse utilizando la lógica de negocio en cualquier otro lugar de la aplicación, pero la abstracción se vería así:

1
<?php
2
3
class Contact_Information {
4
  /* Maintains attributes of the person's contact information. */
5
}
6
7
class Payment_Information {
8
  /* Maintains the credit card number and other information for a person. */
9
}
10
11
class Order {
12
13
  public function submit( $contact_info, $payment_info ) {
14
15
    /* Attempt to submit the order. If the order is successful,

16
     * then return an instance of an Order object with the success status;

17
     * otherwise, return an instance of an Order object with the failed status 

18
     * and a message.

19
     */
20
    
21
  }
22
}

Esta refactorización, aunque pequeño, es lo más grande que hemos hecho en este artículo en particular. Tenga en cuenta que hemos hecho lo siguiente:

  1. Creó una clase Contact_Information que nos permite instanciar un objeto que incluye toda la información de pago de una persona.
  2. Creado una clase Payment_Information que nos permite mantener el número de tarjeta de crédito o de tarjeta de débito para una persona, así como otros detalles asociados con ese método de pago.
  3. Se creó una clase Order, colocó la función submit_order dentro de ella, la renombró a submit (puesto que submit_order sería redundante), y redujo su lista de parámetros a dos valores: una instancia de la clase Contact_Information y la clase Payment_Information.

Para ser claro, este ejemplo no maneja la verificación de asociación entre la información de contacto y la información de pago, ni muestra otras clases que puedan ser necesarias (como si el pago falló o no para la transacción).

Pero ese no es el punto del ejercicio.

En cambio, estamos viendo el olor de código de largas listas de parámetros y cómo podemos disminuirlas usando métodos prácticos y más sostenibles disponibles para nosotros.

Cada vez que está escribiendo una función o haciendo una llamada a una función que requiere un gran número de argumentos, busque formas de refactorizar esa función. Hará que la cohesión del código aumente y el olor disminuya.

Conclusion

Recuerde, los ejemplos que hemos visto más arriba son sólo eso. La lista no es completa, pero son olores comunes que es probable que vea en el código con el que trabaja o incluso el código que escribe. Seré el primero en admitir que soy culpable de esto.

Además, hay muchos, muchos recursos que están disponibles cuando se trata de identificar y fijar los olores del código. Por suerte, también tenemos una serie de herramientas a nuestra disposición que nos ayudará a descubrirlos automáticamente y limpiarlos.

Y allí es donde nos dirigimos. Específicamente, vamos a usar PHP CodeSniffer para ayudarnos a evitar olores de código en nuestro código. Entonces, vamos a ver cómo incorporar las reglas de WordPress en PHP CodeSniffer y conectarlo a nuestro IDE de elección.

Como se mencionó anteriormente en este artículo, el siguiente artículo de la serie se centrará más en los olores de código al escribir código para WordPress. Vamos a echar un vistazo a algunas herramientas y recursos disponibles para ayudar a asegurarnos de que estamos evitando los olores de código, y para ayudar a asegurarnos de que estamos escribiendo un código más fuerte.

Mientras tanto, estudie los ejemplos anteriores y eche un vistazo a los recursos que he proporcionado, ya que son excelentes lugares para aprender más sobre los olores y la refactorización de código de personas y lugares que son notables dentro de nuestra industria.

Recuerda, puedes tomar todos mis cursos y leer mis tutoriales en mi página de perfil, y puedes seguirme en mi blog y / o Twitter en @tommcfarlin donde hablo de varias prácticas de desarrollo de software y cómo podemos emplearlas en WordPress.

Por favor, no dude en dejar cualquier pregunta o comentario en el feed de abajo, y trataré de responder a cada uno de ellos.