Tactical Forking

By Fausto De La Torre, Director of Platforms and Cloud – Europe, Thoughtworks

There are occasions in which multiple teams with different needs and business priorities work on the same code base, which infers communication and overhead in coordination between them at different moments of the development cycle, increasing the cycle time, time to recover from errors, etc..

Due to this (and many other reasons) many teams choose to decouple themselves from the rest, taking their domain elsewhere. For this, many use techniques such as the Strangler Application, creation of an Autonomous Bubble or even seek to migrate their domain to a new application completely independent.

These approaches are effective when dealing with legacy systems or with third-party systems, however, when it comes to applications in constant evolution, these approaches require a great effort before beginning to obtain a real benefit; There are times when they are simply endless efforts.

When we think of taking off a piece of the system to another side, what comes to mind is an extraction: take off a piece from the whole (figure 1), however, another way to see it, it is to keep the piece and remove the rest (figure 2)

Figure 1

Figure 2

Under this line of thinking, we could duplicate the application and begin to get rid of the components that are not of our interest. In this way one of the teams can get its own version of the application and start working on it, by reducing the coordination with the other team. This approach is called Tactical Forking

What is sought with this approach is to obtain the benefit from the first moment in which each team can have its own workflow and path to production without affecting another team.

How does Tactical Forking work?

Forking (Duplication)

It is necessary to create a copy of the system and its deployment mechanism (tests, pipelines, etc.).

Routing

It is necessary to have a routing mechanism that allows users or consumers to access the different parts of the systems

Refactoring

This is a key point, it is necessary to constantly refactor the code of the new application eliminating unnecessary code to have a more maintainable code base.

Use cases

Microservices

When we are implementing a microservice architecture, and we start with the Monolith First approach, we can reach a state in which the component has several domains that need independence.

Multiple teams

There are occasions in which an application was developed by a team and then other teams joined the same code base to implement other modules with different business needs, reaching a state in which there is too much coordination and communication for deployment, Correction of errors and even blockades to commit in the code due to pipelines broken by other equipment.

Considerations

Take into account the components that when they change require changes in both copies of the application, for example: non-modular css files that are not served in a cdn.

Finish the work, I mean reach the final state otherwise you will have two or more monoliths with a lot of code that is useless and can produce unexpected errors.

Mind the “Tactical” in the name (Tactical Forking), it’s the first step, not the last one.

Advertisement

Trabajo remoto, una perspectiva de empresa y de equipos

Cuando el trabajo remoto pasa de ser un diferenciador a ser un mecanismo de subsistencia empresarial.

En este espacio quiero abordar este tema desde un ángulo diferente: más allá del individuo, cómo hacerlo eficiente desde una perspectiva de equipo y de empresa.

Las crisis traen oportunidades, y no con esto quiero minimizar su efecto en la sociedad o peor aún justificarlas. El Covid-19, sin ahondar en la enfermedad, sino en los efectos sociales en el colectivo, nos ha llevado a la sociedad a adoptar nuevas formas de desempeñar nuestras actividades acelerando la necesidad del trabajo remoto.

El trabajo remoto, no es una tendencia aislada que sucede ahora, venía siendo una respuesta a las necesidades que las empresas toman en cuenta para atraer al talento joven, a personas con obligaciones en el hogar e incluso desde un punto de vista más consciente, las organizaciones lo están considerando como una ayuda al ambiente reduciendo la necesidad de transporte, sin embargo la situación actual hace que este tema sea más relevante que nunca.

En opinión personal, dudo que el efecto del trabajo remoto se revierta completamente, aún superando la crisis actual, la “normalidad” cambiará y las empresas se verán forzadas a adaptarse a una nueva realidad. Es por eso que traigo a colación algunas lecciones aprendidas por más de 6 años en ThoughtWorks brindado servicios de consultoría tecnológica de manera remota y más de 20 años de aprendizajes colectivos de esta empresa brindando servicios distribuidos.

Desde la perspectiva de la empresa

El trabajo remoto debe ser considerado una capacidad empresarial

Más allá de que una persona pueda hacerlo o que haya sido adoptado por un equipo, las organizaciones deben mirar el trabajo remoto como una capacidad empresarial a desarrollar.

Algunos humanos son capaces de tocar un instrumento musical de manera extraordinaria; en un principio las actividades y rutinas asociadas requieren esfuerzos deliberados hasta que la capacidad sea desarrollada, es entonces cuando las melodías, que para un novato son imposibles, para los expertos son tan fáciles que las ejecutan sin siquiera pensarlo mucho.

Así mismo las organizaciones que desarrollan capacidades, pueden concentrar sus esfuerzos en temas más complejos basados en las habilidades que como organización han adquirido.

Si bien esta no es una guía de cómo desarrollar una capacidad de negocio, mi intención es poner sobre la mesa algunas experiencias en trabajo remoto que pueden hacer este camino más fácil.

Promover la cultura organizacional en un contexto diferente, por supuesto que esta modalidad trae cambios, y las organizaciones se deben adecuar a ellos, sin embargo la misión y los valores de la empresa buscan permanecer en el largo plazo, el reto es cultivarlos y promoverlos en un entorno un tanto diferente.

Reaccionar rápido y tener en cuenta el largo plazo, si bien las crisis o emergencias pueden llevar a reacciones inmediatas, no quiere decir que esas acciones y formas de trabajo puedan perdurar en el tiempo. Adaptar la visión de cómo trabaja la organización será necesario. La empresa debe comunicar las acciones inmediatas pero debe comunicar el plan o el anhelo de ir más allá de eso, los colaboradores luego de un tiempo se pueden sentir inconformes con una forma de trabajo improvisada.

Tomar en cuenta a todos los individuos como parte del todo, los colaboradores deben saber que están respaldados por una organización, que no están aislados, que hay una diferencia entre ser un “freelancer” que trabaja desde su casa y ser un colaborador de una organización que trabaja desde su casa.

Promover espacios virtuales de comunicación grupal, no solo para hacer comunicaciones oficiales, sino también espacios de discusión y conversación activa entre individuos y equipos. Abrir debates, buscar temas donde la gente pueda exponer sus ideas.

Buscar encuentros frente-a-frente periódicamente, el tener la capacidad de trabajar remotamente no significa que se lo tenga que hacer siempre, nada se compara a hablar con alguien personalmente, las conexiones creadas en este tipo de encuentros perduran en el tiempo, especialmente cuando la organización no nació remota.

Confiar en los equipos y promover la autonomía, existe la creencia todavía de que si no se ve a las personas en el sitio de trabajo entonces no están trabajando, hemos visto que el nivel de autonomía cuando no hay supervisión directa, aumenta (al menos en nuestra experiencia), siempre y cuando las expectativas estén claras, los objetivos definidos y las facilidades instauradas.

La gente se desgasta más trabajando remoto, las organizaciones deben tomar en cuenta que los individuos, trabajan más al estar desde casa; después de un tiempo de generar costumbre, las distracciones disminuyen y el tiempo de enfoque al trabajo es mayor por parte del individuo, temas como lesiones o el desgaste intelectual (efecto burnout) deben ser considerados.

Remoto desde el ingreso, cuando una nueva persona ingresa a la organización, quizás no sabe cómo hacer trabajo remoto; si se quiere adquirir esta capacidad empresarial, la organización debe ofrecer a los nuevos colaboradores desde su onboarding, los implementos, el instructivo, los estándares de herramientas y capacitación, así como exponerlo a ambientes de trabajo remoto desde el inicio.

Los sistemas de comunicación deben ser oficializados, seleccionar herramientas de software para videollamadas, mensajería instantánea, email.

Reconocer que todos pueden trabajar remoto, tener la capacidad de trabajar remoto, quiere decir que cualquier persona o equipo lo pueda hacer, o incluso en casos de crisis o emergencias, que todos lo tengan que hacer al mismo tiempo. Tener un plan de cómo proveer la infraestructura e implementos necesarios es indispensable.

Asegurar y/o proveer a los colaboradores de implementos y servicios para poder trabajar desde su casa de manera eficiente: audífonos, parlantes, cámaras, micrófonos, computadoras portátiles, monitores, internet de alta velocidad, etc.. En estos momentos estamos viendo cómo incluso la prestación de sillas y escritorios son necesarias. Proveer kits básicos de trabajo remoto al momento de que un nuevo colaborador ingresa a la organización (al menos audífonos de alta calidad).

Redes y mecanismos de acceso seguros, es primordial que las empresas tengan un plan (no improvisado) y ciertos estándares implementados para el acceso remoto hacia sus servidores, bases de datos, aplicaciones, etc. El NIST, por ejemplo emitió una guía en 2016 para empresas de cómo hacerlo.

Instalar software de acceso seguro en las computadoras de todos los colaboradores para acceder a la red interna de la empresa desde el primer día de ingreso e.j.: clientes VPN si la empresa lo maneja.

Asegurar el acceso a los proveedores de servicio, no solo a los colaboradores.

Se amplían los límites de contratación, las empresas ya no estarán limitadas a contratar personas que vivan en su misma ciudad.

El espacio físico cuando una empresa comienza a institucionalizar el trabajo remoto, quizás el espacio físico no tenga que crecer en la misma proporción que antes.

Los horarios pueden cambiar ya que muchas personas podrán optimizar el tiempo de transporte y empezar sus actividades más temprano..

Nuevos proveedores, las organizaciones buscarán nuevos proveedores para adecuar espacios remotos de sus colaboradores.

Desde la perspectiva de los equipos

El todo es más que la suma de sus partes.

Cuando hablamos de un equipo no solo hablamos de un grupo de personas que trabajan juntas, sino de un ente que ha desarrollado una cultura, una forma de trabajo, valores compartidos y metas que van más allá del individuo. Hemos visto como aspectos de la cultura de un equipo se mantienen incluso cuando todos los miembros originales han sido reemplazados.

CULTURA

La entidad (equipo) debe ser tomada en cuenta además de los individuos y es indispensable que alguien tome la batuta.

  • En nuestros equipos, las buenas prácticas del trabajo remoto se han convertido en un hábito, sin embargo cuando trabajamos con clientes que no están acostumbrados a esto, el designar un “champion” del lado del cliente, que es quien aboga por velar que estas las buenas prácticas se cumplan, es necesario.
  • Si todavía estas prácticas no se han convertido en un hábito es recomendable que alguien tome la batuta y abogue por ello.

Escoger un horario, puede ser el mismo que cuando todas trabajaban presencialmente, sin embargo, cuando están trabajando desde casa, el tiempo utilizado en el transporte, es utilizable y puede ser excusa ideal para iniciar y finalizar antes.

Conservar y crear nuevas prácticas y rituales, si se solía trabajar de manera presencial y ahora se cambia a un esquema remoto, hay que buscar la manera de adaptar las prácticas para que sean amigables de manera remota e ir cambiando de a poco, evitar cambios bruscos de forma que la cultura vaya evolucionando no destruyéndose.

Introducir el trabajo remoto en las retrospectivas intencionalmente o hacer retros específicamente para este tema.

Tener en cuenta a las personas como individuos y ser empáticos, crear espacios virtuales intencionalmente de conversación personal, ser tolerantes a los nuevos espacios de trabajo, no todos tienen una oficina en su casa.

COLABORACIÓN

Utilizar una pizarra virtual, muchas veces es necesario dibujar, cuando las personas están Cara-a-Cara se levantan y utilizan una pizarra, al estar remoto se necesita un board virtual colaborativo (Mural nos ha ayudado mucho). Se puede tener un board dedicado como si fuera un pizarrón, al que todos tienen acceso.

Incluir la sala virtual en todas las invitaciones de las sesiones de trabajo y todos los links de documentos, presentaciones, etc.. que vayan a ser utilizados.

Todo digital, si bien parece obvio a veces no lo es, cuando estamos trabajando de forma distribuida hay ocasiones que dos o más personas se encuentran juntas y por la facilidad se tiende a utilizar la pizarra y poner una cámara para que la gente vea, o utilizar el board de avance de trabajo (kanban, scrum) físico y poner una cámara: esto hace que la comunicación y la conversación sea aislada y dominada por la gente que se encuentra junta y se excluye a los demás miembros.

Si uno está remoto, el equipo está remoto, basta con que alguien en el equipo no se encuentre físicamente para que el equipo esté en modo remoto, esto implica que todos los que estén juntos se comuniquen mediante la herramienta de mensajería instantánea o que incluso todos se unan a las videollamadas desde sus computadoras para las reuniones de trabajo.

VIDEOLLAMADAS

Una sola herramienta para videollamadas, hay muchas en el mercado, el escoger solo una ayuda a que los plugins, los drivers, etc. se hayan configurado y funcionen bien para todos, a veces el tener dos herramientas, una con el cliente y otra para nosotros, ocasiona inconvenientes como que el micrófono o audio a veces no sirve si sales de una herramienta y entras a otra, entonces reiniciar la computadora o re configurar algo es necesario.

Considerar criterios claves al escoger una herramienta: que permita mute/unmute fácil, incluso en pantalla completa o compartida, que se pueda compartir la pantalla con varias opciones, en Zoom por ejemplo se puede elegir la ventana a compartir, de esa forma se pueden ver notas al momento de hacer una presentación. Tener en cuenta que existen herramientas de videollamadas que tienen limitaciones en cuanto a miembros conectados o a tiempo de duración.

Videollamada grupal siempre abierta en la que todos los miembros puedan estar conectados siempre; si alguien se encuentra en otra llamada es comprensible que no esté conectado, se recomienda unirse a la llamada grupal en cuanto sea posible, esto ayuda a crear un sentido de equipo y transparencia.

Cámara prendida, parlantes/audífonos abiertos y micrófonos cerrados para todos los individuos.

Micrófono y monitor compartido, si hay miembros del equipo que se encuentran juntos es recomendable prender también un micrófono central y un monitor conectado a la videollamada grupal.

Dos monitores si es posible para cada miembro del equipo, uno para su trabajo personal y otro para proyectar la videollamada grupal siempre visible.

MENSAJERÍA INSTANTÁNEA

Oficializar una sola herramienta de mensajería instantánea para el equipo. Siempre hay preferencias diferentes: slack, telegram, hangouts, etc., pero el tener solo una es esencial para fortalecer la comunicación como equipo y evitar conversaciones aisladas.

Considerar criterios claves al escoger una herramienta, al momento de evaluar considerar una que permita tener varios canales, etiquetar personas, notificaciones, versión móvil y de escritorio, que se pueda instalar en varios sistemas operativos, que permite saber fácilmente cuáles son los mensajes no leídos.

Instalar en el teléfono móvil: la energía eléctrica y la conexión a internet no son tan fiables como quisiéramos, al menos la telefonía móvil suele servir en esos casos. No hay que olvidar de silenciar las notificaciones luego del horario convenido.

Contestar rápidamente y respetar los horarios convenidos, el uso de estas herramientas es justamente para tener interacciones inmediatas, si un mensaje llega, lo esperado es una respuesta rápida, es por ello que al momento de enviar un mensaje hay que ser consciente de los horarios convenidos y del tiempo de los otros que pueden estar enfocados en otras tareas.

Solo para respuestas rápidas, evitar utilizar este medio para temas que no requieren una respuesta rápida.

No utilizar el chat de videollamadas, si la herramienta de mensajería instantánea no es la misma de las videollamadas entonces evitarla al momento de enviar links o cualquier texto, oficializar toda comunicación de este tipo en la misma herramienta, en ocasiones en una llamada es necesario enviar el link de una presentación o un extracto de un mail y por facilidad se utiliza, por ejemplo, el chat de Zoom, la desventaja es que los mensajes en el chat de Zoom son volátiles, y no siempre son visibles para las demás personas que se unen después.

CANALES

Un canal principal del equipo, para mantenerse siempre atentos.

No hay sobre comunicación, si alguien va a estar desconectado por algún motivo por mas de 10 minutos es importante notificarlo: AFK 15 min, volví, buenos días, etc. hacen que la cultura del equipo no se pierda.

Abrir un canal informal: a veces es necesario distraerse, un chiste, memes, etc. y en ocasiones el canal grupal no es el mejor mecanismo, aquí caen todos los mensajes que no requieren una respuesta rápida o ninguna en absoluto.

Mantener la relevancia en los canales, frases como “No lo ví”, “Se me pasó” u otra similar son un buen indicativo que gran parte de los mensajes no son importantes para los miembros.

Evitar conversaciones muy específicas entre dos personas en los canales grupales, quizás es necesario una llamada.

Canales por intereses comunes, dependiendo de las necesidades se pueden abrir otros canales donde se traten temas específicos de un grupo que no son relevantes para todo el equipo.

Evitar la proliferación de canales, Si bien abrir un canal es fácil, la consecuencia es que las personas no saben que seguir o dónde colocar sus mensajes.

La mensajería instantánea no reemplaza al correo electrónico. El email es la mejor manera para tener conversaciones importantes que pueden ser tratadas de manera asíncrona.

Preferir videollamadas cuando se requiere mayor comunicación, si es una conversación importante y/o requiere acción inmediata cambia a una videollamada inmediatamente.

Toda innovación es producida por una necesidad, ya sea de motivación interna o por agentes externos, que hace que las organizaciones se adapten a un nuevo entorno para poder seguir siendo relevantes.

El trabajo remoto no es algo nuevo, pero hoy es mas importante que nunca. El efecto que esta crisis esta causando en cuanto al trabajo remoto no se revertirá del todo; esta crisis solo aceleró la adopción de esta práctica que seguirá permeando en la organizaciones y la sociedad generando efectos colaterales y un cambio de cultura al que tendremos que adaptarnos todos.

Paremos las migraciones de sistemas legados, lidiemos con ellos.

Muchas empresas buscan migrar sus sistemas a una arquitectura moderna estrangulando aplicaciones legadas y adoptando microservicios. Estas empresas están enfrentando la migración como el problema a ser resuelto haciendo grandes inversiones, sin embargo están dejando de lado el problema real que los sistemas legados están ocasionando en relación a la incapacidad de agregar nuevas funcionalidades y acelerar el time to market.

“Migramos y luego nos movemos rápido”.

Aunque a primera vista luce como una solución atinada, el problema de las migraciones buscando un “feature parity” es que el beneficio es percibido únicamente cuando la migración se haya completado, porque solo es en ese momento cuando se pueden agregar las nuevas funcionalidad que el negocio requería, sin embargo el objetivo es obtener los beneficios desde el primer momento de la inversión, y no al final cuando quizás ya no exista el presupuesto, o la prioridad de las iniciativas haya cambiado.

Migrar sistemas buscando feature parity a una nueva arquitectura implica, muchas veces, un camino sin fin, en donde el momento en el que la migración “finalice”, habrán aparecido tantas nuevas herramientas y tecnologías que la nueva versión será obsoleta o legada incluso antes de ver la luz.

El tema no está en cómo migramos los sistemas para que luego nos den resultados; el foco debería ser en cómo lidiamos con estos sistemas legados para que sean un catalizador y no un obstáculo al momento de atender los requerimientos de negocio.

Con el uso adecuado de patrones de arquitectura como autonomous buble, capas de anticorrupción, open host, sincronización de fuentes de datos mediante eventos, etc. se puede enfrentar los problemas típicos sin una necesidad imperiosa de migrar los sistemas por completo para obtener resultados positivos, sino generando valor de negocio desde etapas tempranas, haciendo implementaciones pequeñas con beneficios rápidos evitando grandes inversiones que dilatan la generación de valor con apuestas futuras que no siempre llegan a ver la luz.

La pregunta no está en cómo migramos sino cómo lidiamos con los sistemas legados para que puedan apalancar nuevas ideas e implmentaciones en un ecosistema mixto.

Funciones de Aptitud (Fitness Functions)

Cuando creamos una arquitectura, lo hacemos con un propósito, y muchas (o todas) las veces pensamos que la arquitectura que estamos ideando antes de iniciar el desarrollo es la que va a cumplir el propósito, que puede ser asegurarse del rendimiento, auditabilidad, escalabilidad, mantenibilidad, etc. (los llamados requerimientos no funciones)

El hecho es que muy pocas veces (o nunca) en realidad verificamos que el propósito de la arquitectura ideada se esté cumpliendo. Así mismo cuando nos encontramos desarrollando las aplicaciones y evolucionando la arquitectura (todas las arquitecturas evolucionan), no sabemos en realidad si el desarrollo de una solución está “respetando” o preservando la arquitectura o los principios de arquitectura, y nos damos cuenta cuando ya es muy tarde.

Parte de los conceptos de una arquitectura evolutiva son las funciones de aptitud (fitness functions) que en esencia, tratan de hacer verificables las características principales de arquitectura que guían una solución de manera constante e incremental.

Es así que cuando estamos diseñando una arquitectura nos preocupamos de que la solución sea escalable o mantenible (bonitas palabras), pero que significa que sea escalable, que tenga “buen” rendimiento o que sea mantenible, justamente es aquí donde entran las fitness functions, buscando hacer más objetivas estas características mediante mecanismos de verificación constantes.

Por ejemplo: si decimos que una arquitectura busca que la solución tenga “buen” rendimiento, entonces necesitamos crear una(s) función de aptitud que defina que significa “buen rendimiento”, creando un mecanismo de control que verifique en cada nueva versión de la aplicación que las operaciones o transacciones más importantes no tomen más de medio segundo en ser ejecutadas; esta función de aptitud puede ser ejecutada en el proceso de integración o entrega continua antes de liberar un nueva versión a producción.

Si buscamos que sea mantenible y entendemos que una de los aspectos para que la solución sea mantenible es crear una arquitectura en capas dónde buscamos que solo existan dependencias en una dirección (figura 1), entonces debemos crear una función de aptitud que verifique las dependencias entre paquetes sean solamente las que hemos definido (figura 2).

Captura de pantalla 2018-02-27 a la(s) 15.41.53

figura 1 –  Arquitectura en Capas

Captura de pantalla 2018-02-27 a la(s) 15.57.12

figura 2 – Función de aptitud que analiza dependencia entre capas

Dado que cuando estamos construyendo arquitecturas evolutivas buscamos soportar un cambio incremental y guiado a lo largo de múltiples dimensiones, es importante saber hacia donde estamos guiando el cambio y es aquí donde las funciones de aptitud juegan un papel principal, ya que son controles que nos permiten identificar si las características principales de arquitectura se están preservando al mismo tiempo que la arquitectura evoluciona, o en otras palabras: Las funciones de aptitud nos permiten identificar si la arquitectura está evolucionando hacia donde queremos que evolucione.

Anticorruption Layers

That panic moment when the decision of changing the application X which our systems depend on is made.

When we build systems, most of the times those systems depend on or need external or third party applications. The moment when one of these external applications need to be changed or an updated is needed is when the problems don’t stop.

The biggest problem most of the time is not the new application or the new version doesn’t have the same features than the older one (in fact they tend to have cooler features or more of them), the problem is that our system is invaded with dependencies of the external application; the problem is that our domain is corrupted by an external domain.

Screen Shot 2016-06-29 at 3.59.57 PM

For instance, we have a system (green boxes) that manages, besides other features, files and documents, so it has been decided to use a file repository like Alfresco or FileNet (yellow box). Alfresco (or any other tool) provides libraries or API’s that are used by our system to make the integration. In this point our system/domain has an external dependency along multiple components, and that’s why we say our domain is corrupted because the external domain is allocated everywhere. The moment we will decide to switch the the yellow box by a red one we will need to seek every single dependency in our domain and make the change for the new one.

We can avoid this problem introducing an Anticorruption Layer (a term coined in the book DDD) that allows us to isolate the external or third-party dependencies, whether these are tools, systems, libraries, different domains, etc..

Screen Shot 2016-06-29 at 4.14.17 PM

The idea is to build a layer between our domain and the external dependency. This layer is the responsible to do the transformations in both ways; it means, transform the components of our domain into components that the external tool can understands, and vice versa. This way we can isolate the dependency in one single place, so our domain (green boxes) is focus on solving the problem, and any change in the external dependency won’t affect substantially our system behavior.

Conway’s Law in Software Architecture

In 1967 M. Conway enunciated a phrase at the end of his publication How do committees invent?. This phrase was made popular by Fred Brooks on his book The Mythical Man-Month with the name of Conway’s Law.

“… organizations which design systems … are constrained to produce designs which are copies of the communication structures of these organizations.” M. Conway – 1967.

Although this is not a scientific law, it is a valid proposition for many environments, and we can perceive it in our workplace or in other companies that develop software.

The organizational structure of a company will reflect in the systems produced by this organization; if there is an invoicing department, there will be an invoicing system for sure, if there is a notifications area, a system called NOTSYS (with such a cool name) will exist, the finance department will have a FINSYS, and so on, and the systems will integrate with each other in the same way the organization departments communicate.

This law also plays a role at the construction time of every of these systems, because the architecture of these products will reflect the communication structure of the teams that are part of that process.

Due to this fact, if the technology department is organized around technical capabilities, with a work group focused on the user interface, other group to the database, other to the infrastructure, other to the process management, another to the implementation of business logic on the server side (figure 1) the architecture of the resulting systems (figure 2) will be very similar to these communication structures.

Technical organization of teams
figure 1 – Technical organization of teams

Architecture driven by technical capabilities
figure 2 – Architecture driven by technical capabilities

Systems are dynamic, there will always be changes, and these are often caused by changes to the business definitions; if an organizational structure is driven by technical capabilities, every change in the business definitions will require work from all the technical areas of the organization, budget and time assignment, etc. This is one of the reasons why some organizations try to group requirements to “optimize” time and resources, lengthening the development process until all the necessary work can be “justified”, which leads to the business insatisfaction towards the technology department.

In the other hand, we can find organizations that favour multidisciplinary or cross-functional teams formed by different roles and guided by the business capabilities (figure 3) where changes produced by new business definitions are executed from begin to end by just one team avoiding processes overhead, producing different, and often more distributed, architectures (figure 4) with greater evolution capacity.

Organization of teams driven by business capabilities
figure 3 – Organization of teams driven by business capabilities

Arquitectura guiada por el negocio
figure 4 – Business Driven Architecture

In the end, software is the product of an intellectual and collaborative process that will reflect the ideas of the people involved in this process and the communication structures between teams, as we have seen. Due to this, we should take in account this law at the time when we are structuring teams depending on what we want to achieve.

Translated from the original in Spanish. Thanks for the translation Carlos Oquendo @andres19_05

Ley de Conway en la Arquitectura de Software

División de equipos por capacidades de negocio

En 1967 M. Conway enunció una frase en la conclusión de su publicación How do committees invent? a la que Fred Brooks, la popularizó con el nombre de Ley de Conway en su libro The Mythical Man-Month.

“… las organizaciones que diseñan sistemas … están limitadas a producir diseños que son copias de las estructuras de comunicación de estas organizaciones.” M. Conway – 1967

El hecho es que a pesar de no ser una ley científica, es una proposición que es válida en muchos entornos y se la puede evidenciar en nuestro lugar de trabajo o en otras empresas que producen software.

La división organizacional de una empresa se verá reflejada en los sistemas que esta organización produce; si existe un departamento de cobranzas, de seguro existirá el sistema de cobranzas, si existe un área de notificaciones habrá un sistema llamado SISNOT (sí que somos originales para los nombres), el departamento financiero a su vez tendrá sus SISFIN, etc. y los sistemas se integrarán o se comunicarán entre ellos tal como se comunican las divisiones de la organización.

A su vez esta ley también entra en vigor al momento de la construcción de cada uno de estos sistemas, la arquitectura de dichos productos reflejará la estructura de comunicación de los equipos que forman parte de este proceso.

Es así que si el departamento de tecnología está dividido por conceptos técnicos, encontrando grupos de trabajo destinados a la interfaz de usuario, otro grupo a la base de datos, otro a la infraestructura, otro al manejo de procesos, otro a la implementación de lógica en el lado del servidor (figura 1); la arquitectura de estos sistemas (figura 2) será muy similar a estas estructuras de comunicación.

Screen Shot 2016-07-26 at 11.13.44 AM
figura 1 – División técnica de los equipos de trabajo

Arquitectura guiada por aspectos técnicos
figura 2 – Arquitectura guiada por aspectos técnicos

Los sistemas son dinámicos, siempre existen cambios y generalmente estos son ocasionados por cambios en las definiciones del negocio, si se favorece una división organizacional por capacidades técnicas, cada cambio en la definición del negocio exigirá trabajo, asignación de presupuesto, tiempo, etc. en cada una de las áreas técnicas que componen el grupo de trabajo; esta es una de las razones por las que en algunas organizaciones se tiende a agrupar requerimientos para “optimizar” el tiempo y los recursos, alargando el proceso de desarrollo hasta que “justifique” todo el trabajo que se debe llevar a cabo, lo que lleva a la insatisfacción del negocio con respecto al departamento de tecnología.

Por otro lado podemos encontrar organizaciones que favorecen equipos multidisciplinarios o multifuncionales que son compuestos por diferentes roles y guiados por las capacidades del negocio (figura 3) donde los cambios producidos por nuevas definiciones del negocio son ejecutados de principio a fin por un solo equipo evitando la sobre gestión de estos procesos, produciendo arquitecturas diferentes (figura 4), generalmente más distribuidas y con mayor capacidad de evolución.

División de equipos por capacidades de negocio
figura 3 – División de equipos por capacidades de negocio

Arquitectura guiada por el negocio
figura 4 – Arquitectura guiada por el negocio

A la final el software es producto de un proceso intelectual colaborativo, por lo que reflejará las ideas de las personas que intervienen en este proceso y como hemos visto de las estructuras de comunicación entre equipos; es por ello que tomar en cuenta esta ley nos vendría bien a la hora de estructurar los equipos dependiendo de qué queremos conseguir.

Architecture Process – Example

The business problem

Recently I had a requirement because of a new retention policy regulation: we need to store certain files the company generate among all the business units, into one single repository, this repository is a third-party out of our control tool.

Additionally we have few applications where files are generated, uploaded and saved; a couple of mechanisms are used, for instance in one application the files are saved into the database (I don´t know why but they are), in other system the files are stored in the Distributed File System, and another one uses ftp to load files.

We saw a good opportunity to change the heterogeneous way to deal with files across all the applications, looking for a reusable solution based on the business capabilities related with files and document management in an homogeneous way.

Drilling down features and restrictions

After a couple of sessions with the stakeholders and the BA’s, we could determine what are the minimum features that will enable the usability of the solution, as well we defined which restrictions we should keep in mind.

Business requirement / Restriction
Required Capability
The business could change eventually the third party tool for other tool.
Decoupling of implementation
The third party tool is the final repository for certain documents not all of them, we have to handle diverse final repositories as DFS, DB, FTP, SharePoint, etc.
Decoupling of implementation
Files will be stored in one repository or other depending on certain rules like the type of document, business unit, date, etc.
Extensibility
We don’t have any access to configure, start or stop services in the third party tool or any other tool.
Decoupling of implementation
<Conformist Approach, Anticorruption layer>
Just the entitled users can access to send and retrieve documents.
Secure
Users should always be able to upload files no matter if is the third party tool selected or any other tool is unavailable.
Reliability
Rules change always, the business need a fast answers to change.
Agility, Extensibility, Maintainability
Something can go wrong with third party tools, we need to handle errors in a friendly way to the user.
Reliability
We should avoid change the user experience for loading and retrieving files.
Synchronous
Loading and retrieving files duration time shouldn’t increase.
Efficiency

Designing before coding

Designing before coding? Yes, I know I say that; maybe some of my agile colleagues will fight with me just for the phrase, however I truthfully think that we must analyze the problem and of course even create diagrams to transmit the idea and represent the solution somehow before the implementation (responding to change over following a plan, is not the same as responding to change and not have a plan).

Decoupling and reusing

We decided to create a new software component to encapsulate all the business logic to manage documents (see Figure 1); in this way we can implement the new requirement on top of this artifact, and other new related requirements, reducing the changes in the applications that will use it.

Screen Shot 2016-07-22 at 10.31.33 AM
Figure 1: The very first design

Creating the architecture

“A software architecture begins as the result of the collective set of design choices made by the team that created the very first version of a system” [Beyond Software Architecture]

In the same way we need a MVP, we need a MVA (Minimum Viable Architecture) to build the product.

Among dev meetings and conversation with the business stakeholders, through the creation of sketches (See Figure 2) and whiteboard drawings, we ended up with an initial plan.

Screen Shot 2016-07-22 at 10.31.43 AM
Figure 2: One of the architecture sketches

The plan was presented validating the requirements and restrictions in a high level perspective, walking through different scenarios based on BA’s experiences.

We need to keep in mind that this is a plan, and plans can change, because requirements can change, technology can change, we are not Nostradamus “to know certainly the future” and assert that the proposal will cover all the requirements before implementing, however having a plan allows us to start building some components with a vision of the product.

Screen Shot 2016-07-22 at 10.32.04 AM
Figure 3: The solution

Explaining the architecture

The solution (see Figure 3) is based on queues and asynchronous processing of document and files, it is based as well in independent deployable components. These decisions were made based on maximizing the reliability, scalability and decoupling over other requirements.

One of the first things we need to understand is that we have two concepts here: Documents and Files. A Document is a concept that will contain basic business information like the business unit, type, application that generated and the file. A File is the actual binary file that will be stored in one external storage.

We need to know that the only big purpose of this is creating and retrieving documents in a secure and reliable way.

Document Service

It is the only entry point for the petitions of the different consumers, consumers can’t access to files nor documents without going through the services that this component expose (Security). It has its own data base to store and retrieve the information of the documents, and the only necessary information to ask for retrieving and storing files.
In order to attach files to the created document, this component will send messages to the “newDocuments” queue to be processed asynchronously for the “DocumentProcessorManager” component.
In order to retrieve files this component will use the “FileStorageService” component.

Document Processor Manager

This component reads the messages delivered in the “newDocuments” queue, through the “FileCompass” determine where the file should be stored, and delegates the storing implementation to the “FileStorageManager” component. FileCompass is a lightweight component which knows, based on a set of rules (persistent rules, maybe a csv file or DB), where the file should be stored.

File Storage Manager

The responsibility of this component is communicate with the different external storage clients for retrieving and creating files, as well handling the errors when external storages won’t be available.

External Storage Clients

With the “FileStorageManager”, they will conform the anti corruption layer [Domain Driven Design] to decouple the solution of the external storages.

Error Handling queues

The purpose of these components is assure the reliability of the application; these queues will handle the errors when the external storages won’t be available. When is not possible to retrieve a file, the request will be sent to “deliverFiles” queue, so when the service is available again the file will be sent through an email or other mechanism. When is not possible to store a file, the file will be saved in a local FileSystem and the request will be sent to “movingFiles” queue, so when the service is available again the processor will read the messages in the queue and will store the files where it was suppose at the beginning.

Explaining the interaction between the consumers and the Document Service allows us summarize the solution from the consumers point of view, this is interesting for devs who will only use the new solution, and for the BA’s to understand the effort that will require add more consumers (Extensibility)

Creating a Document

A document will be stored synchronously and will send the message to attach the correspondent file asynchronously, this way we can guaranty that the request is saved and eventually the file will be attached. (see Figure 4)
Screen Shot 2016-07-22 at 10.32.17 AM
Figure 4: Document Creation Sequence

Retrieving a Document

To retrieve just the information of the document without a file :

HTTP GET …/documents/7895

To retrieve a File inside a document:

HTTP GET …/documents/7895/file

Conclusions

Everything is a trade off

We tried to generate a solution to satisfy all of required capabilities, of course that was not possible, in pos to get some capability we minimize other ones, in software, everything is a trade off. e.g. In order to assurance the reliability we need to sacrifice the efficiency or the synchronous processing. In order to decouple components we need to sacrifice the efficiency again. So we started to prioritize the required capabilities with the stakeholders really quick, doing questions like: “if you have to choose between, having a 2 seconds respond when the file is uploaded, against not be sure if the file can be uploaded because eventually some of the third party repositories won’t be available, Which one would you choose?”, we could get answers like we must to create a solution that won’t depend on the third party repositories, even if that means more time in the uploading or even if we need to change the user experience to not process files synchronously; in that sense we could identify the “must to do” requirements/capabilities.

Benefits

  • Easy to scale
  • Reliability – Error handling
  • Decoupled from third party storages
  • We have 2 (DocumentService, DocumentProcessor) deployable artifacts
    • Scale independently
    • Deploy independently
  • There is no need to deploy the consumers when a change is introduced in the document services
  • Responsibilities are segregated into different artifacts

Pitfalls

  • Change current error handling (new or unknown scenarios)
  • Current user experience will change
  • Eventual Consistency

Capas de Anticorrupción

Ese momento de pánico cuando se decide cambiar la aplicación X de la que depende nuestro sistema.

Cuando construimos sistemas, la mayoría de las veces, estos dependen o necesitan de aplicaciones externas o de terceros. El momento en que una de esas aplicaciones externas necesita ser cambiada o se necesita hacer una actualización es cuando los problemas no cesan.

El mayor inconveniente muchas veces, no es que la nueva aplicación o versión no tenga las mismas funcionalidades que la anterior (de hecho muchas veces tiene más), el problema radica en que nuestro sistema está invadido de dependencias de esta aplicación externa; el problema es que nuestro dominio se ha visto corrompido por un dominio externo.

Screen Shot 2016-06-29 at 3.59.57 PM

Por ejemplo: Tenemos un sistema (cajas verdes) que maneja entre otras funcionalidades,  archivos y documentos, para lo cuál se ha decidido utilizar un repositorio de archivos como Alfresco (caja amarilla). Alfresco (o cualquier otra herramienta) provee librerías o API’s que son utilizadas por nuestro sistema para la integración. En este punto nuestro sistema/dominio tiene una dependencia de la herramienta externa a lo largo de varios componentes, por lo que decimos que nuestro dominio está corrompido ya que la herramienta externa (que puede ser un dominio diferente) esta “regada” por todo lado. El momento en que decidamos cambiar la herramienta Amarilla por una Roja se deberá buscar todas las dependencias en nuestro dominio y hacer el cambio hacia las nuevas dependencias.

Podemos evitar este problema introduciendo una Capa de Anticorrupción (término acuñado en el libro DDD) que nos permiten aislar las dependencias externas o de terceros, sean estas herramientas, sistemas, dominios diferentes, etc.

Screen Shot 2016-06-29 at 4.14.17 PM

La idea es construir una capa intermedia entre nuestro dominio y la dependencia externa, esta capa es la responsable de hacer las transformaciones en ambos sentidos, es decir; transformar los componentes de nuestro dominio en componentes que pueda entender la dependencia externa y viceversa. De esta forma logramos aislar esta dependencia en un solo punto, de tal modo que nuestro dominio (cajas verdes) esté enfocado en resolver el problema puntual para el que fue diseñado y que cualquier cambio en la dependencia externa no afecte mayormente al comportamiento de nuestro sistema.