Una historia sobre lo que debe tener en cuenta para construir una arquitectura de calidad para su proyecto. Cómo hacerlo insumergible y clientes satisfechos.
A continuación consideraremos ejemplos de la vida real e intentaremos aprender de los errores de los demás. Y en el camino, elaboraremos un libro de recomendaciones útiles para el arquitecto de la solución. En todas las historias: tareas arquitectónicas que comienzan con los requisitos principales del cliente y van acompañadas de una nueva sesión informativa.

El artículo se basa en un informe de Alexey Bogachuk (arquitecto de soluciones de EPAM) de la conferencia
HolyJS 2018 Piter . Debajo de la escena: video y transcripción del informe.
Enfoques para la arquitectura de edificios y el papel del arquitecto del proyecto.
Nadamos - sabemos
Así lo dijeron los marineros del barco sueco Vasa. Simplemente navegaron, huyendo del barco que se hundía, que acababa de bajar al agua desde las gradas. ¿Qué tiene que ver Vasa con eso?

Comencemos con una historia corta que lo hace tener una visión completamente diferente de los enfoques para construir la arquitectura de aplicaciones y el papel del arquitecto del proyecto.
El rey sueco firmó un contrato con el arquitecto constructor naval Henrik Hubertsson. Según los términos del contrato, Henrik tuvo que construir un buque insignia: la belleza de la flota sueca, el mejor barco de Europa. Como patrocinadores principales, el rey y el tesoro participaron en la coordinación de todas las características principales de la nave, como resultado, la orden se formuló de la siguiente manera:
- el barco debería ser el más grande de la flota báltica: 70 metros de largo, 10 de ancho;
- necesitas tres mazos, con capacidad para 300 soldados;
- debe tener 64 armas a bordo en dos filas;
- Se otorgan 3 años para la construcción.

Los análogos de tal barco en este momento no existían. Sin embargo, él mismo tampoco duró mucho, hundiéndose en medio de la celebración de su construcción.
Cuando intentaron descubrir por qué sucedió esto, se descubrió que no había desviaciones de los requisitos. El tamaño es el mismo, la cantidad de armas es normal, los marineros en las cubiertas son exactamente la cantidad que se requería. Sin embargo, esto se combinó perfectamente con el hecho de que las leyes de la física no permitieron que tal recipiente aguante por mucho tiempo en el agua.
Los siguientes errores de cálculo arquitectónicos de Henryk son evidentes (lo que, por cierto, podría haberle costado la vida si hubiera sobrevivido en la corte):
- Todas las restricciones en conflicto no estaban equilibradas.
- No había gestión de riesgos, porque nadie había construido barcos de esta magnitud antes.
- La gestión de la relación con el cliente también estuvo ausente: Henrik no tuvo el coraje de discutir con el rey.
- Se utilizaron tecnologías de construcción incorrectas.
- El arquitecto aceptó requisitos imposibles.
Como resultado de estos errores de cálculo, el barco "cayó" incluso en la etapa de diseño. La historia es instructiva, porque refleja la influencia del ciclo de la arquitectura en la aplicación que se está creando. Hay partes interesadas que formulan objetivos y requisitos, en base a esto, se construye la arquitectura del proyecto y luego el proyecto mismo. Un error en una de estas etapas puede valer todo el proyecto, y a veces la cabeza / trabajo, Henrik Hubertsson no te dejará mentir.
Poderosos amigos
¿Cuántas aplicaciones con la arquitectura incorrecta están muertas antes de escribir la primera línea de código?
El ciclo de la influencia de la arquitectura en el proyecto es el siguiente:

De izquierda a derecha:
- Hay partes interesadas o partes interesadas (en el caso del barco, este es el rey y el tesoro).
- Tienen sus propios objetivos (el primer barco en Europa).
- Los objetivos dictan los requisitos (características específicas del futuro barco).
- A continuación, se realizan dibujos, diagramas y diseños.
- Construcción del proyecto.
Un error en una de estas etapas puede tachar el futuro de su proyecto.
Manual del arquitecto de soluciones
Consideraremos ejemplos de la vida real e intentaremos aprender de los errores de los demás. Al mismo tiempo, compilaremos un libro de recomendaciones útiles para el arquitecto de la solución. Henrik Hubertsson se quemó por el hecho de que no tenía uno.
Si viviéramos en la época de nuestro héroe, cuando los errores en la arquitectura se castigaban con la muerte, este libro se escribiría con sangre.
En todas las historias se darán katas arquitectónicas (tareas). Contendrán una solicitud simplificada con los primeros requisitos del cliente, la esencia del problema y la conclusión.
La historia mecánica de Jimmy
Requisitos del cliente- Reemplace la solución de interfaz de usuario actual.
- Introducir un nuevo enfoque para el desarrollo e implementación de esta solución.
- Necesita una mejor experiencia de usuario.
- Al mismo tiempo, siga todas las mejores prácticas.
- Soporte para varias plataformas.
Lo que se ha hechoLos requisitos son muy generales, no específicos. No está claro qué deben hacer todos con esto. Al mismo tiempo, el equipo de desarrollo está ubicado en Minsk y el cliente está en Montreal. Debido al hecho de que hubo sanciones entre Bielorrusia y Canadá, no se pudo trabajar directamente con Canadá. Se decidió trabajar con el cliente a través de una oficina en Dublín. Debido a todos estos retrasos en el tiempo y la mediación, no fue posible contactar al cliente y finalmente conocer los requisitos, hacer propuestas para la implementación.

Después de un tiempo, cierto Jimmy aún comenzó a responder preguntas y aclarar requisitos, comenzó el desarrollo del proyecto. Jimmy compartió con entusiasmo los consejos, se le quitaron contactos y se mantuvo correspondencia con él directamente. Como resultado del trabajo, se realizó una presentación. Es hora de mostrar los resultados. Se organizó una conferencia con personas importantes del cliente, pero, curiosamente, Jimmy no estaba entre ellos, y nadie sabía quién era. Por supuesto, todo resultó ser completamente diferente de lo que el cliente esperaba. El hecho es que la compañía no conocía a ningún Jimmy, resultó que era un desarrollador ordinario y simplemente compartió su experiencia y consejos. No tomó decisiones y, en general, no tuvo ninguna relación con el proyecto en absoluto.
Cual es el error En la primera etapa de definición de la arquitectura, las partes interesadas se definieron incorrectamente.
ConclusiónCualquier arquitectura comienza con la identificación de los interesados. Para identificarlos, hay muchos enfoques, consideraremos uno de ellos: construiremos una matriz RACI.
Raci
La abreviatura significa: R: responsable, los que implementarán; A - tomadores de decisiones responsables; C - asesoramiento consultado (gente de negocios); I - informado, personas que necesitan estar informadas. Cada una de las partes interesadas debe ser asignada a una u otra categoría. La matriz indica roles y tareas.

Habiendo construido tal matriz, podemos entender quiénes son los interesados.
Además, se observó que entre las partes interesadas hay personas que hacen afirmaciones falsas que hacen a un lado el proyecto. En este caso, resultó que se trataba de representantes de otros proveedores que no estaban interesados en el proyecto. Pero la matriz RACI no sabe cómo distinguir a dichos clientes, para esto hay un enfoque de cebolla.
Cebolla
El enfoque de la cebolla es algo diferente de las matrices RACI.

Su esencia es que las capas se construyen alrededor del sistema, dentro de las cuales se indican las caras de ciertos clientes. En este ejemplo, los desarrolladores, DevOps, los administradores de contenido se comunicarán con el propio sistema. Un poco más arriba en abstracción son las personas de negocios. También hay reguladores externos: medios, leyes, etc. Por ejemplo, para lanzar una aplicación en algunos países, debe aprobar una auditoría realizada por una empresa externa, que revelará la accesibilidad y otras cualidades requeridas del proyecto, estos son requisitos de las partes interesadas externas.
Por lo tanto, escribimos en el manual de nuestro arquitecto que la primera y necesaria etapa es determinar las partes interesadas.
Historia: no lo suficientemente rápido
La empresa tenía un cliente de comercio, en este asunto la velocidad de transacción es muy importante. En base a esto, se formularon una serie de requisitos.
Requisitos del cliente- Se más rápido que los competidores
- Es necesario que la transacción se realice en no más de 0,5 segundos.
Que hizoEl proyecto se completó, pero falló. Por qué Una vez más, los requisitos no eran del todo correctos. El objetivo no era realizar transacciones a una velocidad de 0,5 segundos, sino hacerlas más rápido que un competidor. Como resultado, la velocidad se llevó a 0.5 segundos, pero el competidor en ese momento alcanzó una cifra de 0.4 segundos. Vemos un error al determinar el objetivo comercial. ¿Por qué el cliente necesita un sistema?
Un objetivo comercial es solo la punta del iceberg, detrás de él están los impulsores comerciales, los reguladores y los objetivos internos de la empresa. A menudo permanecen desconocidos. Estamos más interesados en objetivos técnicos, que incluyen un objetivo comercial. Están regulados por principios comerciales, por ejemplo, nadie quiere sacrificar la calidad del trabajo al implementar un objetivo técnico, porque esto es un error de cálculo a largo plazo. Todo esto debe saberlo y tenerlo en cuenta al construir arquitectura. Además del hecho de que los proyectos sin un objetivo están muertos inicialmente.
ConclusiónIncluso si trabaja en startups, cuyo propósito, a menudo, es probar nuevas tecnologías, de todos modos el uso de nuevas tecnologías en el proyecto no es un objetivo comercial. El problema es que si el objetivo es utilizar nuevas tecnologías, el proyecto crecerá constantemente y requerirá nuevas inversiones financieras y temporales innecesarias. Los objetivos comerciales nunca deben pasarse por alto al diseñar una arquitectura.
Puede encontrar recomendaciones útiles en el libro "Descubriendo los requisitos", autores - Ian Alexander, Ljerka Beus-Dukic.

La historia de cómo ordeñaban los pioneros del caballo
Una empresa que vende seguros tiene su propio sitio web. Funciona muy bien y tiene una buena funcionalidad establecida. Ya tiene una lógica empresarial compleja en su lugar.
Requisitos del cliente- Además del sitio, debe crear una aplicación móvil que los empleados usarán en sus teléfonos
- La aplicación debe tener modo fuera de línea.
Que hizoSegún los requisitos, se decidió escribir en React Native. El desarrollo ha comenzado. Durante la primera llamada, se recibieron mejoras y adiciones a los requisitos:
- La compañía emite teléfonos a los empleados, y todos trabajan en Android.
- El cliente solo está interesado en el modo fuera de línea.
- Plazo: dos meses.
Obviamente, la tarea de clasificar un producto de terceros listo para usar con una lógica comercial compleja y escribir uno nuevo en dos meses no encaja en ese marco de tiempo. Se decidió utilizar PWA (Progressive Web Apps).
Ya tenía experiencia con ese trabajo. No solo se escribió una aplicación PWA, sino que fue isomórfica. Se reutilizaron los servicios del servidor en el cliente, se escribieron contenedores especiales con los que podría comunicarse con estos servicios. Se escribió un enrutador que redirigió todas las solicitudes a la base de datos MongoDB; en el cliente, a través del adaptador, trabajaron con IndexedDB. Esquema a continuación.

Entonces, los problemas estaban con los requisitos, que no son tan simples. Considere un ejemplo de cuáles son los requisitos:

Hay un formulario y necesitamos generar errores de validación; si se ingresa la URL incorrecta, debemos mostrar la página 404. ¿Qué tiene de malo los requisitos? Hablan sobre lo que debe hacer el sistema. Pero para el arquitecto, qué sistema debería ser más importante. Si profundiza en lo que debe hacer el sistema, puede profundizar demasiado en los detalles e ir por el camino equivocado. Dichos requisitos se denominan funcionales, también se denominan requisitos MoSCoW. Palabras que a menudo se encuentran en estos requisitos:

Todos los requisitos que contienen estas palabras no le interesan. Si se concentra en tales requisitos, se construirá un sistema monolítico sin ninguna arquitectura especial.
ConclusiónEl arquitecto debe centrarse en los requisitos no funcionales, en particular en las restricciones y los atributos de calidad. El próximo kata sobre esto.
La historia del cuervo blanco.
Requisitos del cliente- Desarrolle un servicio separado que convierta y almacene datos en caché en formato xml.
- Debe hacerlo desde un sistema heredado de terceros.
Que hizoDesarrollamos un buen servicio de trabajo, lo hicimos en Node.js. Así es como el sistema en su conjunto comenzó a verse esquemáticamente junto con el nuevo servicio introducido.

Obviamente, Node.js es una oveja negra aquí, a pesar de que todo funcionó bien.
El error se descubrió durante la transferencia del servicio a clientes que no estaban familiarizados con Node.js. Esta situación muestra perfectamente el papel de identificar restricciones para el proyecto. ¿Cuáles son las limitaciones?
- Técnica
- Tiempo y presupuesto
- Pila de desarrolladores de clientes
ConclusiónEl arquitecto está obligado a averiguar todas las restricciones existentes que pueden afectar el producto final. Las limitaciones son decisiones arquitectónicas que se han tomado antes y para usted.
A continuación, pasamos a los atributos de calidad, tenemos un interés especial en ellos.
Atributos de calidad
Biblioteca muy segura
Hay muchos atributos de calidad, solo tiene que mirar la lista que Wikipedia nos brinda.

La historia se basa en el atributo "seguridad". Cuando visita la biblioteca, apenas espera, usando una computadora allí, que tendrá que pasar por una autorización de dos factores ingresando el correo electrónico, el teléfono y un código de verificación desde el teléfono. Sin embargo, esto sucede. Vemos que la aplicación ciega de atributos de calidad también puede ser difícil.
Teléfono en el bosque
¿Qué pasa con el rendimiento? Está claro que no hay personas a las que no les importe el rendimiento. Aquí está el guión. Supongamos que una persona quiere usar una aplicación móvil desde su teléfono mientras está en el bosque. Por lo tanto, afecta a nuestro sistema, pero no a todo, sino a la interfaz web. Por ejemplo, necesita obtener algunos datos en tres segundos. Este es el escenario de rendimiento que deberíamos obtener.

Es tales casos de uso que un arquitecto debe recopilar para construir un sistema de alta calidad en la salida. Cuando tenemos una lista de requisitos comerciales, atributos de calidad, restricciones, reconocemos a todos los interesados, comenzamos a abordarlos en diagramas de diagrama. Este direccionamiento de atributos en los diagramas se llama tácticas arquitectónicas. ¿Qué tácticas arquitectónicas se pueden aplicar a un sistema telefónico en el bosque según los escenarios existentes?
- Mejore UX para que a una persona le parezca que la productividad es mayor.
- Optimice los recursos (JS, CSS, imágenes, fuentes, etc.).
- Realizar el almacenamiento en caché.
- Agregue trabajadores de servicio, ruta crítica.
- Aplicar compresión
- HTTP / 2.
Sin embargo, en el caso de un teléfono en el bosque, la experiencia de usuario y la ruta crítica no nos convienen de inmediato. Y nuevamente, las tácticas deberían ser dictadas por los guiones. Este es el trabajo del arquitecto, elegir entre todas las tácticas necesarias en un caso particular. Pero una aplicación no es solo una interfaz. El rendimiento también se ve afectado por DNS, backend, bases de datos, y todo esto también se puede optimizar. Hay muchas tácticas sobre cómo hacer esto, pero, una vez más, la aplicación de uno u otro depende del escenario de uso.
Intentemos usar el patrón CQRS (segmentación de responsabilidad de consulta de comando). El uso de este patrón como táctica incluso afecta a varias capas de la aplicación: tanto el back-end como el front-end.

Digamos que hay una base de datos heredada muy lenta, enviamos una solicitud allí y después de diez segundos recibimos una respuesta. Además, se replica y debe realizar entradas en ambas copias. Nosotros en el bosque con un teléfono queremos leer rápidamente nuestros datos de esta base de datos. El patrón dice que debemos separar las solicitudes de lectura y escritura. Agregue una base de datos de lectura rápida. Estamos agregando todos los medios para sincronizar esta base de datos con una existente.

El uso de este tipo de tácticas engorrosas debe estar claramente dictado por los requisitos.
Entonces, usamos algunas de las tácticas. Lanzamos la aplicación y vemos que no ayudó, ya que no hay conexión a Internet. Entonces llegamos a la tolerancia a fallas que el arquitecto de la solución debería encargarse.
Soldado de hojalata firme
Nadie quiere que la aplicación caiga de manera estable varias veces al día, todos quieren tolerancia a fallas.
Para que la aplicación funcione de manera estable, se puede aplicar el principio de falla rápida:
- Siempre verifique los puntos de integración por adelantado.
- Evitar conexiones lentas.
- Revisa tus entradas.
Por qué usar esto, veamos el ejemplo de Lie Connection. Esta es una conexión que quizás algo suena, pero de hecho no funciona. Esto puede suceder entre el cliente y el servidor, la base de datos y el servidor, entre servicios. Aplique el patrón del disyuntor.

Si bien todo va bien, no estamos haciendo nada. Tan pronto como se excede el tiempo de espera, nos desconectamos y después de un tiempo hacemos una nueva solicitud. Si la solicitud vuelve a ocurrir con un error, nuevamente permanecemos en modo fuera de línea con un mayor tiempo de espera. Y si la solicitud salió bien, volvemos al modo en línea. Por lo tanto, este patrón permite verificar los puntos de integración y evitar conexiones lentas.
Submarino
Hay muchos enfoques para proporcionar tolerancia a fallas. Uno de ellos es el mamparo (mamparo, por ejemplo en un submarino). Su significado es que la aplicación está escrita de tal manera que continúa funcionando, incluso cuando ha aparecido un error en uno de sus componentes.
Tenemos una lógica empresarial en la que enviamos datos y recibimos una respuesta. Comenzamos a enmarcarlo con nuestras tácticas, agregar validación, escala. Se ha producido un error en la lógica empresarial. Lo registramos. Como información de error, necesitamos el contexto en el que ocurrió. El problema es que con tal marco lógico, es poco probable que el contexto persista, por lo tanto, necesitamos hacer un volcado de memoria. Un volcado de memoria es algo bastante voluminoso, y los errores de JavaScript ocurren con poca frecuencia, por lo tanto, es una estrategia que es bastante costosa para los recursos informáticos. Necesitamos dividir los errores en críticos y no tan importantes, y volcar solo los primeros.
Cubo con fugas
Una estrategia similar a la descrita anteriormente se utiliza en el patrón Leaky Bucket.

Tenemos contadores para diferentes tipos de errores. Cuando se produce un error, se incrementa un contador de errores de este tipo. Por tiempo de espera, este contador disminuye. Pero si el número de errores comienza a salirse de la escala, el contador no tiene tiempo para disminuir y, en sentido figurado, desborda el cubo, después de lo cual hacemos un volcado de memoria. A continuación, trabajamos en el error que hizo que el contador se desbordara.
Tenga en cuenta que el servicio que implementa este patrón también estará envuelto en tácticas, validaciones y se escalará. Entonces se construye la arquitectura.

¿Qué significan las flechas verdes? Los diferentes servicios interactúan entre sí a través de diversos protocolos, bases de datos y otros servicios.
, , «Patterns for fault tolerant software», — Robert S. Hanmer.

«Software Architecture in Practice», — Len Bass, Paul Clements, Rick Kazman. .

, :

. .
— .
- — ( ).
: , -.
:
- Drupal, - .
- ReactJS VueJS, , , .
quality-, :
- 400 (maintainability).
- , (testability).
- (re-usability).
- (performance).
- (accessibility).
, . C4. .
:

, . , -.
:

-, -, . , - -. .
:

, , Template Service, . - . , , , -.
-? - . , Template Service. , Drupal -. , NuxtJS Next.js, , , Vue.js React.js. GitHub , , JAM-. JavaScript, API, Markdown.

, , , . Node.js - . Drupal -, , CMS, , , . Javascript, API, Markdown .
Conclusión. .
, , , . . , .
?
, , , . -, .
Conclusión, , .

Resumen
, . . , , , :
- (stakeholders).
- - .
- , . , .
- .
- .
- , .
, : 24-25 HolyJS , . — , .