Subjetivamente: la refactorización es una "enfermedad" juvenil. Según observaciones personales, en algún lugar después de 26 años comienza a soltarse. Como en esa vieja frase: "El que no fue revolucionario en su juventud, no tiene corazón, el que no se vuelve conservador en la madurez, no tiene mente". Por lo tanto, hasta que finalmente lo deje, trataré de describir los casos de usuario de refactorización y los posibles objetivos que se pueden lograr con él.
Inspiradores
Comencé a escribir después de la próxima visualización de la solicitud de extracción para más de 150 archivos, donde la nueva funcionalidad y la refactorización del existente estaban ferozmente involucradas. La refactorización no solo fue cosmética, sino también lógica, lo que causó el mayor dolor. Por ejemplo, en Ruby, la amount == 0
reemplazada en amount.zero?
por la amount.zero?
sin considerar que para el caso de nil
en amount
estas construcciones no son equivalentes. Todo esto se explicó aproximadamente de la siguiente manera: "pero según el código, ¡se supone que el estándar es así!" A la pregunta lógica "¿cuál es el propósito de seguir el código al estándar y, en general, cuál es su objetivo como desarrollador?" el hombre se encerró y repitió un poco culpable "pero de acuerdo con el código estándar, tienes que escribir así ..." y parecía un rubio en una tienda de ropa que no podía hacer frente al deseo refactor compra todo
Definición
El tema es delicado, por lo que debe prestar especial atención a la pregunta "¿quién es quién?" Entonces, según la wiki , la refactorización es un proceso de cambio de la estructura interna de un programa que no afecta su comportamiento externo y está destinado a facilitar la comprensión de su trabajo.
Por mi parte, quiero reducir los límites y definir la refactorización (en el peor sentido de la palabra) como cualquier cambio que no esté directamente relacionado con el problema que se resuelve y que no cambie el comportamiento externo del sistema, sino que se realice como parte de la tarea original.
Es decir, no quiero hablar sobre el cambio planeado en la base del código, para el cual se ha delineado el alcance del trabajo y se han establecido objetivos específicos, sino sobre las modificaciones espontáneas que ocurren durante el desarrollo.
Valor del producto
Ahora comenzaré desde lejos. El código fuente no es un objetivo ni un valor. Por supuesto, estéticamente o artísticamente, puede ser de algún interés, pero estas son excepciones. En general, el código es una herramienta para crear un producto de software que cualquiera usa. Por lo tanto, para empezar, sería bueno determinar cuáles son los valores en el producto.
Valores directos del producto
Todo es simple aquí. Usan el producto, por lo que los valores directos son lo que el usuario claramente siente / ve / siente. A saber:
- todo tipo de funcionalidad del producto;
- usabilidad (UI / UX, rendimiento, tolerancia a fallos, etc.).
El segundo punto puede causar alguna discusión. Después de todo, muchos creen que esto no es lo principal. Dado que si la funcionalidad es buena, no importa en qué se envuelva. Buenos ejemplos de funcionalidad sin una UI / UX sana: Redmine y SAP . Sin embargo, no estoy de acuerdo con esta mirada y en opinión más cercana al camarada Alan Cooper y su "Hospital psiquiátrico en manos de pacientes".
Valores indirectos del producto
Estos son valores que en sí mismos no afectan al usuario. Pero pueden "disparar" o "acumularse" y tener un impacto (de gravedad variable) en el producto o su funcionalidad.
- Errores Un caso límite de valores. Son secundarios porque los valores en sí mismos no llevan, sino que se toman de características vecinas.
- Limpieza Se trata de legibilidad, modularidad, minimización de componentes entrantes, estandarización y unificación de interfaces, etc.
- Documentación Se trata de código y explicaciones para desarrolladores, no de descripciones comerciales o cuentas de usuario. Está bien ilustrado por la frase de un campesino alegre de una de las entrevistas: "La lógica en la base de datos está escrita como un libro".
- Escalabilidad / seguridad / seguridad. El usuario no los ve hasta que sucede algo malo.
Valores de desarrollador
Una categoría muy importante que muchos pasan por alto, pero que siempre afecta el resultado.
- Código por estándar.
- Sangría en feng shui.
- Otras transacciones con conciencia. Después de todo, el código fue escrito, por lo que hay un resultado para el día y, por lo tanto, hay un beneficio.
- Cumplimiento del código con el mundo interior.
Pero seamos honestos. Todo esto no se trata de los valores asociados con el producto y el usuario final. Se trata de psicología y cucarachas personales.
Vista desde el lado de los negocios
En aras de la integridad, uno tendría que ver todo esto desde el lado de los negocios, y no un producto de software. En este caso, la división en valores directos e indirectos se vuelve bastante banal: directa - obviamente trae dinero y puede dar una evaluación cuantitativa inequívoca; indirectos: no aportan dinero y / o es muy difícil de cuantificar; los valores para el desarrollador no aportan dinero de ninguna forma (tal vez incluso lo quiten).
Por ejemplo
- Una nueva característica con OAuth atornillando aumentó el número de registros en un 10% y obtuvimos + 1k $.
- Dividimos el módulo de facturación en varias partes independientes, según el patrón de responsabilidad única. Parece que se hizo más fácil de mantener, pero no fue posible medirlo.
- Pusimos la base del código en línea con el código estándar y ... no recibimos nada.
Vale la pena señalar que, a partir de las estimaciones anteriores, las piernas crecen con la querida aceleración comercial, la prisa general y la renuencia a dedicar tiempo a algo que no sea la funcionalidad y, posiblemente, una corrección de errores. De hecho, los valores directos se pueden estimar y "vender", y los indirectos son muy difíciles o imposibles. Y resulta que los valores indirectos se realizan, ya sea en virtud de una formación en ingeniería, o se entienden en un nivel intuitivo, o se descartan como "inútiles".
Para ser justos, aquí debemos recordar el concepto de habilitador, que "allana el camino" para la implementación de la función deseada, pero no tiene un beneficio obvio para el usuario. Pero esa es otra historia.
¿Y qué hay de refactorizar?
Al menos a pesar del hecho de que solo puede influir en los valores indirectos del producto. Por lo tanto, el usuario no se sentirá mejor por ninguna refactorización.
También es importante recordar sobre la entropía. Refactorizar siempre lo minimiza. Para reducir la entropía, idealmente, necesita un equipo de arquitectos que minimice la entropía en la etapa de diseño. Para citar una pieza del Mítico Hombre-Mes:
La programación del sistema es un proceso que reduce la entropía y, por lo tanto, la metaestabilidad es inherente a ella. El mantenimiento del programa es un proceso que aumenta la entropía, e incluso su mantenimiento más hábil solo retrasa la caída del sistema en una obsolescencia irremediable.
Por lo tanto, si consideramos que la refactorización es parte del proceso de mantenimiento del programa, cuanto menor sea la refactorización, más tiempo durará el código sin tener que reescribirlo.
¿Qué objetivos puede tener la refactorización?
Permítame recordarle que estoy hablando de un cambio espontáneo durante la implementación de las funciones, y no de los cambios planificados. En este caso, la definición del objetivo recae completamente en el desarrollador. Debe hacerse la pregunta principal “¿por qué?”, Responderla y luego avanzar hacia la meta deseada.
¡Por entropía!
Es difícil hacerlo tú mismo. Y sacar la revisión generalmente no es realista. El objetivo es ciertamente bueno: despejar la cabeza de puente para nuevos logros, así como limpiar las toxinas y las toxinas acumuladas durante el tiempo de soporte del producto. Pero palear un par de módulos desde cero sin perder nada en el camino no es una tarea fácil. Debe resolverse junto con analistas de negocios y arquitectos, si los hay. Muy pocas personas se arriesgan a hacer esto de forma voluntaria.
Para la documentación!
Ya es más fácil. Cambie el nombre de las variables / funciones según el principio de "lo que está en la caja, luego en la caja", simplifique el diseño debido a las capacidades del lenguaje y las bibliotecas, agregue comentarios en lugares no obvios, etc. Esto se puede hacer solo y, con el enfoque correcto, se puede hacer bien tanto para uno mismo en el futuro como para los colegas vecinos.
Por la velocidad!
Para ser honesto, dicho trabajo debe destacarse como una tarea separada. Dado que las capacidades actuales del sistema son suficientes para usted y no necesita hacer nada, o sabe exactamente qué y cuánto necesita acelerar.
Todo entra en esta categoría: desde la corrección inocuo de N + 1 hasta la aceleración grave debido a cambios en los algoritmos de operación. Todo el problema es que la "paridad" de los errores siempre se encuentra a gran velocidad. He aquí un ejemplo: en una transacción, los datos de la base de datos se envían y en la misma transacción se establece una tarea en Sidekiq; La cola de Sidekiq en Redis y la transacción no se aplica a ella; cuando aumenta la velocidad de la cola, la tarea a veces se ejecuta antes de que se confirmen los datos; Puede imaginarse las consecuencias y el proceso de depuración usted mismo.
¡Para refactorizar!
Imagine que utilizó el servicio de limpieza de apartamentos. Vinieron y comenzaron a limpiar, pero, en el camino, movieron todos los muebles del apartamento y delinearon las cortinas de la sala de estar a la bañera con el argumento "en tales condiciones, la limpiadora fue más agradable para hacer su trabajo". Imagen de "WTF?!" te lo puedes imaginar tú mismo.
Espero que entiendas que no necesitas pensar en ti mismo, sino en quién lo haces.
Humildad y aceptación
En conclusión, es necesario dar un "manual" sobre qué hacer antes de refactorizar. Es cierto que esta no es una lista de TODO, sino más bien una lista de hechos con los que debe aceptar y aceptar o no tomar medidas.
- Estoy aumentando el número de errores en el proyecto y puedo obtener una pandereta para ello.
- Me convierto en el propietario del código refactorizado y, en primer lugar, me enviarán todas las preguntas sobre él.
- Por mis acciones no produzco nada de valor para el usuario final.
Una pequeña explicación
- Cualquier cambio en el código tiene una probabilidad distinta de cero de generar un error. Y dado que esta acción no está conectada con la funcionalidad definitiva, simplemente produce errores sin generar valores centrales. Es bueno estar al tanto de esto y no pretender ser mangueras cuando se le presentan preguntas.
- Las excusas como "anotate anterior" y similares son muy miserables, porque en el mismo github / gitlab no existe tal característica. Además, el autor anterior confirmó que todo funciona en su configuración, y no es responsable de sus cambios y pierde parte de la imagen de lo que está sucediendo. Más precisamente, se lo quitas junto con la responsabilidad.
- Al usuario realmente no le importa la refactorización, está interesado en la estabilidad y la funcionalidad, y la refactorización no se trata de eso.
Y de nuevo: si no está de acuerdo con al menos uno de los puntos, no comience a refactorizar. Mejor lea a Habr, Lurk, beba té o, en el peor de los casos, corte la siguiente característica del tablero.
El final
No juzgues estrictamente. Si es posible, critique constructivamente. Y siempre piense en el propósito de sus acciones. Gracias