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