Sobre linter, calidad de código, calidad en general y gestión de calidad

Tenga miedo de sus deseos; pueden hacerse realidad.
La sabiduría popular

Una pareja deseaba casarse y encontrar la felicidad eterna. Exploté su auto en la iglesia inmediatamente después de la boda.
One Wish Grant, película Ruta 60.

imagen

Otra nota filosófica sobre la gestión, y en este caso la calidad, consta de tres partes: muy abstracta, moderadamente abstracta, concreta y una conclusión separada. Critica la práctica actual de usar linter.

Una parte muy abstracta sobre la calidad.


Primero, quiero hablar sobre la calidad, o más bien sobre la gestión de la calidad de cualquier cosa, sobre un producto en el sentido más amplio, un producto como resultado de la actividad humana, ya sea crear uno nuevo (escribir un código o una imagen, diseñar una nave espacial), cortar el exceso (escultura , molienda, selección de buenos frutos) o transformación (transporte, congelación, envasado, producción de gasolina y plástico a partir de gas).

Un buen producto tiene algunas señales de que es de alta calidad. Diferentes productos tienen diferentes signos. Por ejemplo, las buenas frutas huelen deliciosas, se ven bien, saben bien.

Ahora daré un ejemplo hiperbólico y luego iré directamente al código.

Imagine que tenemos una tienda de frutas y hay un problema, nuestras frutas comenzaron a venderse peor y el competidor tiene líneas directas. Realizamos un estudio y descubrimos que el olor cerca de nuestros mostradores no es agradable para los visitantes. Y es como el olor en las tiendas de un competidor. ¡Oh, encontramos un problema, un índice de satisfacción del visitante por olor! Vamos a resolverlo, hay marketing de aromaterapia, simplemente colocaremos instalaciones automáticas cerca de los estantes y obtendremos un olor maravilloso del huerto de manzanas. Lo hicieron Y el índice de satisfacción del cliente por olor, naturalmente, subió. Solo que ahora hay aún menos compradores.

Si te fijas seriamente, el problema original podría ser completamente diferente:

  1. Nuestros competidores venden frutas de igual calidad, pero comercializaron aromáticamente antes que nosotros y atrajeron a los visitantes con el olor.
  2. Nuestras frutas son buenas, pero las frutas de la competencia son realmente mejores que las nuestras (variedades, almacenamiento, lo que sea)
  3. Nuestras frutas están podridas. Simplemente se pudrieron y apestaron.
  4. Las frutas del año pasado, que están detrás de la vitrina, están podridas y esperamos poder venderlas. Y apestan desde allí.
  5. El competidor tiene más variedad.
  6. El competidor presentó más bellamente sus frutos, en general, los mismos que los nuestros.
  7. Es estúpidamente más barato allí
  8. Allí, el vendedor es hermoso, y en nuestro lugar Baba Manya vino a sustituir ...

Obviamente, solo en el primer caso el marketing aromático nos ayudará. En algunos puede ayudar, pero puede enmascarar el problema real, pero en el tercero no tomará ninguna medida o causará aún más asco. Y, oh, con qué frecuencia el problema es que la fruta está podrida.

De hecho, cuando surge tal problema, es necesario analizar exhaustivamente las causas y en cada caso tomar una decisión específica del caso.

Aún más hiperbólico


Tienes tomates verdes y sabes que solo se venden los rojos. No es necesario pintar tomates. Es bueno que puedas acelerar la maduración con etileno . Y será de plena maduración, no de pintura. Si fuera imposible acelerar, sería necesario tirar estos tomates y obtener otros nuevos, ya buenos.

En otras palabras, si no está satisfecho con la calidad del producto resultante, entonces hay problemas en la cadena de producción y necesita analizar y cambiar el proceso, y no pintarlo en la salida.

Bueno, entiendes el punto. Si algo huele mal, el perfume no ayudará.

Parte moderadamente abstracta sobre la calidad del código


Entre las propiedades de un buen código, encontraremos (sin ordenar por importancia):

  • consistencia de estilo
  • legibilidad
  • rendimiento
  • extensibilidad
  • transparencia de arquitectura y patrones.

Esto se logra principalmente a través de la autodisciplina y el nivel de habilidad de los desarrolladores, así como cuando hay muchos desarrolladores, a través de acuerdos de estilo de código y acuerdos de arquitectura (MVC, MVVM, ECS, miles de ellos). El código de alta calidad apareció mucho antes que linter, cualquier convención y patrones arquitectónicos.
La mayoría de las reglas de linter son puramente cosméticas y resuelven el problema de aumentar la legibilidad del código debido a la aplicación uniforme de prácticas pequeñas y locales. La longitud de las líneas allí, los nombres de las variables, const donde no hay modificación, a veces incluso se introducen restricciones en la complejidad ciclomática de las funciones. No se trata de reglas específicas, sino del hecho de que estas reglas son generalmente cosméticas, ayudan a que el código se vea mejor. La palabra clave aquí es mirar .

Cuando cualquier indicador comienza a usarse como objetivo, pierde su valor como herramienta.
Libre interpretación de la ley de Goodhart .

Ahora dibujemos una analogía con los tomates. No somos lo suficientemente maduros. Una linter automática nos dirá: "Mira aquí y no hay el color correcto". ¿Qué hará el programador? Muy a menudo pintado. Y esta es la idea principal de mi crítica de linter. Ahora daré un ejemplo concreto y luego sacaré una conclusión.

Específicos


PixiJS 2 de febrero de 2018 (hace un año).

Llega el grupo de solicitudes . La conclusión es que anteriormente se usaba un número constante de puntos para dibujar la curva, lo que obviamente no es óptimo. Se propone utilizar un algoritmo astuto para estimar la longitud de la curva. El algoritmo no es ciencia espacial, pero definitivamente no es obvio, publicado en 2013 y citado con un artículo de su autor (hay problemas con https). La felicidad que generalmente conservaba en su página personal.

Hay un código C (16 líneas):

float blen(v* p0, v* p1, v* p2) { va,b; ax = p0->x - 2*p1->x + p2->x; ay = p0->y - 2*p1->y + p2->y; bx = 2*p1->x - 2*p0->x; by = 2*p1->y - 2*p0->y; float A = 4*(ax*ax + ay*ay); float B = 4*(ax*bx + ay*by); float C = bx*bx + by*by; float Sabc = 2*sqrt(A+B+C); float A_2 = sqrt(A); float A_32 = 2*A*A_2; float C_2 = 2*sqrt(C); float BA = B/A_2; return ( A_32*Sabc + A_2*B*(Sabc-C_2) + (4*C*AB*B)*log( (2*A_2+BA+Sabc)/(BA+C_2) ) )/(4*A_32); }; 

Y el siguiente código (JS) se envió al grupo de solicitudes:

 /** * Calculate length of quadratic curve * @see {@link http://www.malczak.linuxpl.com/blog/quadratic-bezier-curve-length/} * for the detailed explanation of math behind this. * * @private * @param {number} fromX - x-coordinate of curve start point * @param {number} fromY - y-coordinate of curve start point * @param {number} cpX - x-coordinate of curve control point * @param {number} cpY - y-coordinate of curve control point * @param {number} toX - x-coordinate of curve end point * @param {number} toY - y-coordinate of curve end point * @return {number} Length of quadratic curve */ _quadraticCurveLength(fromX, fromY, cpX, cpY, toX, toY) { const ax = fromX - ((2.0 * cpX) + toX); const ay = fromY - ((2.0 * cpY) + toY); const bx = 2.0 * ((cpX - 2.0) * fromX); const by = 2.0 * ((cpY - 2.0) * fromY); const a = 4.0 * ((ax * ax) + (ay * ay)); const b = 4.0 * ((ax * bx) + (ay * by)); const c = (bx * bx) + (by * by); const s = 2.0 * Math.sqrt(a + b + c); const a2 = Math.sqrt(a); const a32 = 2.0 * a * a2; const c2 = 2.0 * Math.sqrt(c); const ba = b / a2; return ( (a32 * s) + (a2 * b * (s - c2)) + ( ((4.0 * c * a) - (b * b)) * Math.log(((2.0 * a2) + ba + s) / (ba + c2)) ) ) / (4.0 * a32); } 

El código está diseñado de acuerdo con la configuración de la interfaz. Se indican las descripciones de todos los parámetros, un enlace al algoritmo original, un grupo de constantes, de acuerdo con el requisito de la interfase sin operadores mixtos: se ordenan 1 paréntesis. Incluso para el rendimiento, la API no se realiza de manera objetiva, sino con parámetros separados, por lo que generalmente es mejor en JS.
Hay un problema Este código hace basura completa. (Un intento de marcar la expresión jodida en ruso, que se usa bastante en las publicaciones occidentales para expresar el grado del problema y parece ser apropiado).

Eso es lo que dijo linter al mirar este código sin paréntesis
c:\rep\pixi\pixi.js\src\core\graphics\Graphics.js
258:26 warning Unexpected mix of '-' and '*' no-mixed-operators
258:32 warning Unexpected mix of '-' and '*' no-mixed-operators
259:26 warning Unexpected mix of '-' and '*' no-mixed-operators
259:32 warning Unexpected mix of '-' and '*' no-mixed-operators
260:24 warning Unexpected mix of '*' and '-' no-mixed-operators
260:30 warning Unexpected mix of '*' and '-' no-mixed-operators
260:30 warning Unexpected mix of '-' and '*' no-mixed-operators
260:36 warning Unexpected mix of '-' and '*' no-mixed-operators
261:24 warning Unexpected mix of '*' and '-' no-mixed-operators
261:30 warning Unexpected mix of '*' and '-' no-mixed-operators
261:30 warning Unexpected mix of '-' and '*' no-mixed-operators
261:36 warning Unexpected mix of '-' and '*' no-mixed-operators


Vuelve una longitud enorme, y muchos puntos se destacan en él, es bueno que haya una restricción desde arriba, funcionó. Anteriormente, este modo estaba deshabilitado de forma predeterminada, pero luego se activaba para todos (por cierto, debido a otro error). Fix ya pisoteado por cierto . No me puse en contacto con el autor del commit y no le pregunté por qué decidió poner los corchetes, pero siento que lanzó el linter, cuyo archivo de configuración ya está en PixiJS. Este linter le dijo, su código es malo, porque carece de corchetes, agregue corchetes. La opción "operadores no mixtos" dice que no tiene derecho a escribir

 2*2+2*2 

porque puede conducir a una mala legibilidad. Alguien creó esta opción, luego alguien la incluyó en el proyecto, lo que significa que muchas personas la encuentran útil.

Conclusión


No quiero decir que linter es malo, pero considero que su uso es malo. Nosotros (en el sentido de la humanidad) pudimos automatizar la detección de solo una pequeña parte de los signos de un buen código, principalmente cosméticos como soportes. Las linters son buenas como herramientas para analizar la calidad del código, pero tan pronto como elevamos el cumplimiento de los requisitos de la interfaz al marco del requisito obligatorio, obtenemos este cumplimiento. No ganamos nada más que conformidad. Así es como poner la cámara en una cinta transportadora con tomates y enviar a pintar todos los que no sean lo suficientemente rojos. Hasta que le demos al desarrollador una herramienta para evaluar la calidad de la apariencia del código, él podría enviar un código incorrecto y nosotros podríamos verlo. Ahora el código incorrecto estará mejor disfrazado. Imitará uno bueno, porque tiene todos los signos externos de un buen código. Y perderemos el linter como herramienta de evaluación, porque todo el código es consistente. Teníamos una herramienta de evaluación, pero ahora no está allí, sino el código entre paréntesis, aunque a veces no está allí, pero estos son los detalles. En total, considero que linter es una herramienta genial, pero solo si el cumplimiento de los requisitos no se convierte en un objetivo .

Y sí, aquí podemos decir que no hay pruebas, que no necesita copiar y pegar el código, que esto es desarrollo de stackOverflow, que no inserta código en el proyecto que no comprende. Eso es todo si. Y esta es una señal de mal código. Pero el linter ayudó a hacerlo visualmente similar a todo lo demás en el proyecto. Pero el linter nunca verificará si comprende bien lo que escribió.

En otras palabras, creo que el uso correcto del linter es lanzarlo regularmente en el proyecto como líder y evaluar cómo y qué está sucediendo. Bueno, reglas como más paréntesis para el dios de los paréntesis, básicamente lo considero dañino. Cuando vemos que alguien comete un código de mala calidad, vale la pena entender por qué está haciendo esto y resolviendo este problema a un nivel más profundo. Naturalmente, no necesita formatear el código con las manos, agradezco a los autoformadores de todas las formas posibles, pero hasta que toquen la parte semántica del código de alguna manera. Si obligamos a la persona a llevar el código a los estándares con un linter, esencialmente pintaremos el tomate verde en rojo. Y será aún más difícil entender que en realidad es verde. Qué hacer en proyectos de código abierto con un montón de personas diferentes, la pregunta es más complicada, pero incluso aquí puede pensar qué hacer.

Vale la pena decir que mi actitud hacia linter se formó hace mucho tiempo, hace más de tres años, pero no pude encontrar un ejemplo adecuado en la práctica cuando el linter jugó una broma cruel. Y así lo encontré. El hecho de que lo haya estado buscando durante tanto tiempo dice que el problema no es a gran escala, o lo difícil que es notar el efecto negativo, pero creo que este artículo será útil. Recuerde, un linter es una herramienta y, como cualquier herramienta, puede usarse en detrimento y para bien, y cómo a veces puede cortarse con cualquier herramienta.

Source: https://habr.com/ru/post/440414/


All Articles