Balas de plata o, en resumen, sobre métodos de construcción blanda

Repasemos los métodos de creación de software inventados en unos 70 años de su existencia. No hay tantos como podría parecer. Pero lo suficiente como para quedar perplejo.





Adagio



El hombre es adaptable por naturaleza. Vas, por ejemplo, a la cocina, donde el pollo está girando en la parrilla. El aroma llega a la nariz y, si tienes hambre, incluso salivarás. Después de unos cinco minutos dejas de oler. Lo único que recuerda a la comida es un trozo de carne que gira detrás del cristal del horno con las alas extendidas. El olor sigue ahí, puedes medirlo, pero el cerebro bloquea la información de los receptores.



Esto está sucediendo en todas partes y la ingeniería de software no es una excepción. Comenzamos con "descubrimientos maravillosos" que "el espíritu de la iluminación nos prepara", pasamos sin problemas a la rutina, la vergüenza y el scrum, los sprints-shmints, la encapsulación-polimorfismo-nacionalidad y, oh mierda, un trozo de carne es girando en el horno, amenazando con quemarse hasta el final, a pesar de la estimulación material regular por encima del promedio del hospital.







En la década de 1960, un hombre curioso llamado Richard B. Doss descubrió que en Estados Unidos, saturado de adicción al trabajo protestante, el 70-80% de la gente trabaja muy por debajo de su capacidad para trabajar. Además, a diferencia de un manipulador robótico, un trabajador de proteínas puede cortarlo rápidamente. Los estudios se repitieron en "cero" y "décimas" con el mismo resultado. Tal situación afecta la salud, por decirlo suavemente, no importa.



El propósito del texto no es disuadirlo de una productividad insuficiente ni darle ningún consejo. Solo repasaremos brevemente los métodos de creación de software inventados en unos 70 años de existencia.



Tres maneras



No tiraré de la goma, comenzaré con lo principal. Solo hay tres formas de desarrollar software. Sí, tres es un buen número, hermoso. Entonces:



método de arriba hacia abajo . Es entonces cuando al principio piensan globalmente "qué hacer", luego "cómo hacerlo", y luego lo hacen, si queda tiempo.



Camino ascendente . Es entonces cuando lo hacen por primera vez, poco a poco, en pequeñas partes. Piensan "qué, sí cómo" sólo sobre esta parte, sin molestarse con lo global y perdurable.



Camino en espiral . Empezamos a pensar globalmente, pero cuando suena la alarma, nos despertamos y desplegamos el prototipo. Y así varias veces, acumulando experiencia, hasta que aparece una solución acorde a los requerimientos.



Desarrollo de arriba hacia abajo



En el lenguaje común, todos los métodos de arriba hacia abajo se denominan "cascadas". Si ya le han dicho sobre la existencia de varios ajiles, entonces tal "simplicidad es peor que el robo" debería despertar sospechas.



El descenso del método a las masas se produce en la década de 1960, complementando orgánicamente los requisitos de la programación estructurada para lavarse las manos antes de comer y utilizar cubiertos y servilletas. La tarea global se dividió en subtareas más pequeñas, que, a su vez, en otras aún más detalladas, y así sucesivamente hasta el nivel de un bloque estructural que se puede implementar directamente en un lenguaje de programación. Por cierto, las pruebas para estos bloques se escriben en paralelo, hola a los TDD de la década de 1960.



El proverbio ruso "Mide siete veces, corta una vez" es casi el método de arriba hacia abajo.







En la versión ortodoxa de la "cascada", la retroalimentación del cliente llega solo después de que se realiza la entrega. Trabajamos durante un año, sacamos el piano de los arbustos, resultó "no del todo bien", se necesitan algunos toques finales. Mientras tanto, el cliente ha dado a luz a una larga lista de nuevas funciones. No estar acostumbrado a trabajar en tal esquema es un poco tonto. Por tanto, en una versión humana, es posible volver a la etapa anterior para aclarar desde cualquier punto, resultando en una "cascada con retornos".



Las ventajas del método son claras. Cuanto más pensado al principio, menos trabajo innecesario tendrá que hacerse en el medio y al final. Se excluyen múltiples reinvenciones de bicicletas, duplicación de funciones y errores.



Sin embargo, si inicialmente hay muchas funciones, entonces no es fácil dar a luz el desglose correcto. Necesitamos buenos analistas, diseñadores con experiencia en estas áreas temáticas. E incluso en este caso, existe el riesgo de retrasar la planificación de la implementación durante un período indecente.



En el futuro, el método se mejoró repetidamente, por ejemplo, el método V , donde las etapas de desarrollo a lo largo de la pendiente izquierda de la letra "V" corresponden a las etapas de pruebas y aceptación del ascenso a la derecha. El nivel horizontal muestra inmediatamente qué documento de proyecto del contratista sirve como base para el documento de aceptación del cliente.



Está claro que las mejoras no pueden superar las limitaciones fundamentales del método. Por eso tienen principios. Esto no significa que el método sea malo. Simplemente tiene riesgos de este tipo. Si puede defenderse de los riesgos, entonces todo está bien, comenzamos a pensar y disfrutamos de los beneficios en el camino.



Desarrollo upstream



De hecho, el método ascendente es incluso más antiguo que el descendente. En la década de 1950, Fortran y Cobol ya existían, pero no había una idea clara de cómo construir software. Por eso, actuamos de la manera más natural: hoy haremos una cosa, mañana otra, luego algún día la pegaremos en una tercera. Si necesita implementar varias tareas, seleccionamos las más importantes.







A veces, el método también se denomina incremental, aparentemente por analogía con i++



. Se agregó una función: incremento. Si desea estirar el globo en la proyección de Mercator, también puede llamar al método espiral incremental, pero más sobre eso más adelante. También les gusta representar el método en forma de ciclo, aunque para i++



los valores finales no están definidos, por lo que tendrá que "excavar" desde aquí hasta la hora del almuerzo. Continuando con el tema de los proverbios rusos, tenemos un dicho "gira como una ardilla en una rueda": se trata solo del método ascendente.



La técnica fue y sigue siendo la más típica para el desarrollo interno. Sus programadores tienen que hacer lo que la empresa necesita ayer. Para pensar de manera más global, la década de 1960 vio el surgimiento de "casas de software" , grandes oficinas de diseño para el desarrollo de sistemas personalizados, incluidos monstruos como IBM .



Toda esta construcción de software ascendente continuó sin cambios significativos hasta la década de 1990. La batalla principal para hacer coincidir las teorías académicas con la práctica de la ingeniería ha pasado por alto el refugio seguro porque se libró en la jungla de los métodos de arriba hacia abajo y en espiral.



En la década de 1990, hubo una fuerte tendencia a reemplazar a los programadores "domésticos" por consultores externos. Una de las razones es la complicación de las tecnologías y la especialización, que es difícil de lograr dentro de la empresa para la que la ingeniería de software es una actividad no fundamental. El software para el hogar ahora está desarrollado por equipos temporales Shabashnikovcontratistas. Las relaciones han cambiado y el cliente no es un especialista en todas estas metodologías, análisis y arquitecturas. El cliente, en el mejor de los casos, sabe cuáles son los problemas individuales y puede priorizarlos. El equipo del contrato, a su vez, no sabe lo suficiente sobre el negocio del cliente para planificar la implementación completa.



En tal situación, nuevamente parece apropiado un método simple función por función. Pero trabajar con un contratista con salario diario requiere más supervisión que los trabajadores asalariados a tiempo completo. El enfoque debe adaptarse, evitando trámites burocráticos. De hecho, para "emitir los términos de referencia" se requiere una planificación general y documentos relevantes, es decir, vollensnolens, uno tendría que cambiar a métodos formales de arriba hacia abajo o en espiral. ¿Y por qué lo necesita una empresa de transporte o un fabricante de automóviles, por ejemplo? La gente solo quiere resolver un pequeño problema interno, calcular el salario allí o reducir el calendario de vacaciones.



La demanda crea oferta, a fines de la década de 1990, los llamados métodos ágiles aparecieron, como mínimo, permitieron al cliente mantenerse al día y el contratista comprendió gradualmente lo que, de hecho, estaban implementando.



Qué ha mejorado:



  • la planificación es todavía corta, pero cubre más de una función, y su grupo, mientras que el plazo de la etapa es estrictamente limitado;
  • se mantiene un registro de lo que se hizo;
  • teóricamente, debería asignarse tiempo para simplificar y limpiar el código (refactorización);
  • en teoría, los riesgos de regresión deben contrarrestarse con pruebas exhaustivas.


¿Por qué estoy escribiendo "teóricamente"? En la práctica, cuando el presupuesto es limitado o hay problemas de tiempo, estos dos puntos se sacrifican en primer lugar. La "vaca sagrada" en los ajiles no es la calidad del código, como pretendían los autores, sino la fecha límite para la siguiente función.



Duplicación de código, complicaciones innecesarias, pospuesto "para posteriores" implementaciones ineficaces - si no limpia lo que se hizo antes, entonces la deuda técnica crece. Cuanto más tarde se pague la deuda, más tendrá que pagar al final: tiempo, días-hombre, errores, fallas, trabajo lento, etc.



Después de unos 10-15 años, los autores del "Manifiesto de Ajaila" comenzaron a hacer sonar la alarma.: "Chicos, ¿qué están haciendo? Queríamos decir otra cosa". Son algo correctos, el desarrollo de abajo hacia arriba es tan simple y tan convincente que todos estos procedimientos adicionales parecen innecesarios.



Resumamos lo bueno del desarrollo de abajo hacia arriba. En primer lugar, el umbral de entrada se reduce drásticamente. Empezar desde cero no requiere costosos expertos en análisis y diseño con experiencia. Aunque toda la construcción puede durar indefinidamente, pronto se van a levantar los primeros cuarteles, y ya puedes empezar a instalarte en ellos. Es más fácil gestionar el proceso, los puntos de control y los objetivos locales son transparentes.



Los problemas, como en el caso de las “cascadas”, son fundamentales. Es más fácil administrar el proceso, pero casi imposible: el resultado final, ya que no se registra claramente en ninguna parte. Los riesgos se transmiten al cliente: deje que el propietario del producto piense que tiene una gran cabeza. Si el equipo hace frente a la arquitectura técnica con experiencia, pruebas y refactorización (hasta cierto umbral de complejidad), entonces la arquitectura funcional es mala. La simplificación del enunciado del problema, la misma "refactorización", ahora el modelo de dominio, ayudaría a deshacerse del código elegante y costoso de mantener, pero no hay nadie para hacerlo. Y no hay modelo, para ser honesto, toda la semántica está en la cabeza y en el código.



Pero no hay razón para estar molesto, recuerde el sprint más desastroso de la historia mundial: 5 días de creación y mil quinientos millones de años de refactorización continua.







Ingeniería espiral



Las limitaciones de la “cascada” antes mencionadas se hicieron evidentes en la década de 1970, luego de la implementación masiva de las metodologías correspondientes como SADT / IDEF . Al mismo tiempo, trabajamos en métodos ascendentes en proyectos “domésticos” con otros problemas, lo que creó la sensación de un callejón sin salida. Por lo tanto, los investigadores desconcertados por el problema (principalmente Barry Boehm ), rascándose los nabos, emitieron a mediados de la década de 1980 una visión actualizada del proceso de construcción de software en forma de espiral .







La lógica del razonamiento en "espiral" es aproximadamente la siguiente. Sí, a medida que crece la complejidad de las tareas, dedicamos cada vez más tiempo al análisis y al diseño, el riesgo de errores en esta etapa es cada vez mayor. Pero al implementar funciones individuales sin un plan general, corremos el riesgo de cometer errores y terminamos con partes ineficaces o simplemente incompatibles. Por lo tanto, dejaremos en paz el diseño de la "vaca sagrada", pero a) limitaremos el marco de tiempo yb) comprobaremos rígidamente las decisiones tomadas, desplegando un prototipo completo.



El punto "b" es muy importante. Con el desarrollo de abajo hacia arriba, también produce algo constantemente, correcciones de errores allí, nuevas funciones. Pero funcionará si el sistema ya está en funcionamiento y en mantenimiento. ¿Y si no? Imagine que un cliente quiere un sistema de control de tráfico de trenes y, en un par de semanas, le muestra pantallas para ingresar información sobre el material rodante y un simulador de horarios. No seriamente.



El prototipo debe incluir la mayoría de las funciones, incluso si no está completamente implementado o incluso con "stubs". Del prototipo completo, respectivamente, obtenemos comentarios completos: aquí se equivocaron, no entendieron la esencia de los requisitos, no tuvieron en cuenta el entorno operativo, allí el formato de salida no coincide con el formato de entrada, etc. Con esta valiosa retroalimentación, comenzamos la segunda ronda de la espiral, creyendo razonablemente que la posibilidad de llevar el próximo prototipo al nivel de un producto terminado es alta. Para sistemas de tamaño medio (hasta un millón de líneas de código aproximadamente), dos o tres iteraciones son suficientes.



Por lo dicho, está claro que atribuir la espiral a métodos incrementales es tan ridículo como lo son las ballenas para pescar, aunque ambos tienen cola.



¿Qué tiene de bueno la espiral? Reducimos drásticamente los riesgos de desplegar al cliente en lugar de un producto, francamente avanzando, pero al mismo tiempo no sacrificamos el diseño. Es decir, se mantiene la visión global de la situación, el resultado final se puede gestionar calculando el presupuesto y la ganancia. Todos, cliente y contratista, pueden ver la luz al final del túnel. El cliente, si es serio en sus intenciones, tampoco gritará: "¿Por qué me pones la cola y luego deslizas mi trompa, enséñame todo el elefante?" En cada vuelta, todo el elefante es visible.







Sin embargo, en comparación con la creciente ingeniería de software, es imposible administrar un pelotón de programadores-técnicos sin analistas y diseñadores, y tendrá que explicar este delicado momento al cliente para justificar un precio más alto. Después de la etapa de diseño de la primera ronda, los especialistas no permanecen inactivos, sino que continúan ocupándose de la tarea, esperando comentarios, pero en la ronda final lo más probable es que no sean necesarios en absoluto. La duración de la bobina puede ser de varios meses, pero normalmente cuesta de dos a tres. No parece un sprint extremo semanal, pero tampoco parece una expectativa anual de un producto. Tampoco es fácil elegir cuándo, en esta etapa, “basta con diseñar” y es el momento de empezar a colocar ladrillos.



La implementación más famosa y exitosa de la técnica en espiral - MSF(Marco de soluciones de Microsoft). Más tarde, Microsoft tuvo una versión recortada, perfeccionada para métodos ascendentes y comercializada como MSF para Agile para proyectos y equipos relativamente pequeños.



En lugar de un epílogo



El abuelo Brooks describió cuatro tipos de software que la gente crea en su libro más vendido .







La imagen muestra que en algún momento puede dejar de "simplemente escribir un programa" y "por un precio exorbitante" quiere convertirlo en un producto (algo que se suministra a muchos clientes diferentes) o un complejo (algo que consta de muchos programas y se integra perfectamente en el entorno del cliente, incluido el equipo). Y si "escribir un programa", en general, puede ser cualquiera de los métodos de construcción suave, entonces sus excelentes planes para un mayor desarrollo pueden verse interrumpidos por las deficiencias de los métodos de arriba hacia abajo y de abajo hacia arriba.



En las condiciones en que el recurso humano de los programadores-técnicos es excesivo con escasez y dificultades para contratar diseñadores y analistas, en lugar de una organización horizontal (los “ingenieros de sistemas” hacen una plataforma para los “postulantes”), comienzan a utilizar una vertical. , donde cada equipo implementa sus funciones en base a sus propias bicicletas. Desde el punto de vista de la gestión, el segundo método parece más simple, pero solo hasta el momento en que se introduce un comando de "arquitectura" horizontal, que, a través de una larga persuasión y coordinación, reduce los riesgos de los mismos errores repetitivos.



En esto, quizás, podamos detenernos, porque la orientación inicial en el espacio de la información debería ser suficiente. Hay palabras clave y algunos enlaces en el texto, por lo que los curiosos pueden profundizar más en el tema.



Texto original en el sitio "Mecánica de la ingeniería de software"



All Articles