Introducción al curso

1

Introducción al curso de Profesional de Arquitectura de Software

Atributos de calidad

2

Definición

3

Atributos: Idoneidad funcional

4

Atributos: Eficiencia de ejecución

5

Atributos: Compatibilidad

6

Atributos: Usabilidad

7

Atributos: Confiabilidad

8

Atributos: Seguridad

9

Atributos: Mantenibilidad

10

Atributos: Portabilidad

11

Tensiones entre atributos

12

Analizando PlatziServicios

Patrones de arquitectura

13

Patrones monolíticos vs distribuidos

14

Patrones: Modelo Vista Controlador

15

Patrones: Capas

16

Patrones: Orientado a eventos / Provisión de eventos.

17

Patrones: Microkernel - Plug-ins

18

Patrones: Comparte-nada

19

Patrones: Microservicios

20

Patrones: CQRS

21

Patrones: Hexagonal - Puertos y adaptadores

22

Patrones: Diseño orientado al dominio

23

Combinando patrones de arquitectura

24

Analizando nuevamente PlatziServicios

Diseño de una arquitectura

25

Pararse en hombros de gigantes

26

Herramientas y partes de un diseño: Tipos de conectores

27

Conectores: Llamado asincrónico / sincrónico. Modelo Cliente servidor.

28

Conectores: Enrutador, difusión

29

Conectores: Pizarra, repositorio, colas, modelo PUBSUB

30

Escenarios y tácticas

31

Escenarios: Disponibilidad, detección, reparación

32

Escenarios: Reintroducción y prevención

33

Escenarios: Mantenibilidad

34

Escenarios: Prevenir efectos dominó y diferir enlace

35

Escenarios: Eficiencia de ejecución

36

Escenarios: Seguridad

37

Escenarios: Capacidad de prueba

38

Escenarios: Usabilidad

39

Validar las decisiones de diseño: Arquitectura en evolución

40

Último análisis a PlatziServicios

Modelado y documentación de arquitectura

41

Cómo comunicar la arquitectura: Vistas y Puntos de vista

42

Documentación vs implementación

43

Conclusiones del curso

You don't have access to this class

Keep learning! Join and start boosting your career

Aprovecha el precio especial y haz tu profesión a prueba de IA

Antes: $249

Currency
$209
Suscríbete

Termina en:

0 Días
5 Hrs
32 Min
3 Seg

Escenarios: Prevenir efectos dominó y diferir enlace

34/43
Resources

How to prevent domino effects in software systems?

Ripple effects in software frequently occur when a change in one module generates the need to change many others, potentially impacting the entire system. Preventing these effects is crucial to improve software maintainability and is mainly achieved through information hiding and interface maintenance.

Why is information hiding key?

Information hiding is a tactic that promotes encapsulation, a fundamental principle in object-oriented programming. By allowing a module or object to hide certain pieces of information, you ensure that external agents rely on a stable interface and not on internal details that can change.

For example, if you have a module that calculates taxes, you can provide a public interface that handles this calculation consistently, regardless of how the details of the internal calculation may change over time. This reduces the risk of internal changes affecting other modules that rely on this functionality.

How to maintain a robust interface?

Maintaining an interface involves clearly defining how other components or services interact with your module through a consistent set of functions or methods. By establishing a single interface that handles all necessary interactions, any internal changes will not affect external users of your service.

For example, if you have to add an additional step to the calculation process, as long as the external interface does not change, the clients of the service will not be affected. This is essential for a more robust and easily upgradable system.

What is the role of intermediaries in programming?

Intermediaries act as bridges between non-compatible modules or components, helping to manage changes in interfaces or messages without affecting the stability of the system. In object-oriented programming, patterns such as FASAD, PROXY or ADAPTER allow developers to decouple components and facilitate system evolution over time.

What is Demeter's law and how does it apply?

Demeter's law, also known as the principle of least knowledge, suggests that a module or component should only know the other modules directly related to it, not the dependencies of its dependencies. By limiting these connections, you reduce the risk of introducing errors when an intermediate component changes.

A classic example is when you manage purchase orders: instead of navigating directly through several connected objects to get information from the seller of a product, you can directly ask the main object (in this case, the order) for the sellers, thus maintaining limited knowledge and modular interaction.

How to take advantage of polymorphism and component replacement?

Polymorphism allows objects to change their behavior on the fly, depending on their state or instance type. Using this feature, especially common in object-oriented programming, is key to defer bindings and provide flexibility in implementing functionality.

When to use component replacement?

Component replacement allows the upgrade or replacement of a module without altering the system. This is possible if components are regularly linked at load time, allowing their renewal without the need to stop the system.

Imagine an application that uses plugins: you can update or change a component by simply installing a new plugin that complies with the same interface, giving the system the ability to adapt without compromising stability.

What benefit do protocols bring to software architecture?

Adhering to well-defined communication protocols, such as JSON or XML, is crucial for modules to communicate effectively regardless of their internal changes. This not only facilitates maintainability, but also ensures that modules can be deployed independently, promoting a modular and efficient software architecture.

How to implement configuration files effectively?

Using configuration files to define how different parts of the system are connected is a common practice. These files allow you to adjust the configuration and interactions between modules dynamically, without the need to recompile the system. They are especially useful in plugin architectures where configurations can dictate which extensions or services are used in each case, providing flexibility and control over the software workflow.

Contributions 12

Questions 2

Sort by:

Want to see more contributions, questions and answers from the community?

Apuntes:

Prevenir efectos dominó. Trabaja estrictamente con las dependencias. Es decir, cuándo podemos detectar que un cambio generaría problemas en otros módulos u otras dependencias.
• Ocultar información. Cualquier módulo u objeto que diseñemos, tenga la capacidad de ocultar cierta parte de la información para que los agentes externos no dependan de esa información puntual sino de una interfaz clara que no puedan cambiar por más que la información cambie. De esta forma podemos garantizar que, si el cambio de la información es importante, los dependientes no necesiten cambiar porque están pasando por una interfaz que no cambió.
• Mantener la interfaz. Si tengo un servicio que hace algo, la dependencia a ese servicio va a ser a través de una interfaz clara, de lo contrario cualquier acción cuándo cambie puede poner en riesgo el módulo.
• Restringir comunicación. Para generar sistemas que estén acoplados de forma ligeras, en vez de conocer las dependencias de tus dependencias, siempre te limites a tus dependencias directas, de esta forma cualquier cambio en la forma que tus dependencias trabajan no afecta al módulo en el que estás trabajando.
• Intermediarios. Hablamos de un punto dónde podamos compatibilizar a un módulo con otro y si dejan de ser compatibles, estos intermediarios puedan servir como punto de compatibilidad.

Diferir enlace. Habla sobre cómo podemos hacer para que un cambio en nuestro código no requiera desplegar toda la aplicación completa.
• Registro en ejecución. Cuando un módulo o servicio depende de otro, si dependen fuertemente van a requerir estar compilados juntos. Si nosotros podemos diferir esa compilación y que se registre un servicio en momento de ejecución, es decir que se ponga disponible a sus dependencias en el momento de ejecución, podemos hacer que estos servicios se puedan desplegar independientemente.
• Archivos de configuración. Van a servir para en momento de ejecución saber cómo conectar varias partes. Es imprescindible que nuestros módulos dependan de interfaces y no de implementaciones específicas.
• Polimorfismos. Un objeto pueda comportarse de forma diferente en base a su estado. A través del polimorfismo podemos postergar la forma en que se resuelve un problema dependiendo de qué instancia del objeto será.
• Reemplazo de componentes. Tener la capacidad de desplegar un componente y luego desplegar su reemplazo, o quizás otro componente que respete esa interfaz, y que todo el resto de nuestra aplicación no necesite cambiar.
• Adherir a protocolos. Nos permite tener un protocolo claro entre dos módulos y no necesitar saber la instancia específica o el tipo específico de un módulo.

Ley de Demeter o el principio de menor conocimiento, esta ley dice que para generar sistemas que estén acoplados de forma ligera en vez de conocer las dependencias de tus dependencias siempre te limites a hablar con tus dependencias directas. De esta forma cualquier cambio en la forma en la que tus dependencias trabajan no afecta al modulo que estas trabajando.

Escenario: Mantenibilidad

Estimulo: Pedido de cambio / Nuevo requerimiento

  • Prevenir efectos domino
    • Ocultar información
    • Mantener la interfaz
    • Restringir comunicación
    • Intermediarios
  • Diferir enlace
    • Registro en ejecución
    • Archivos de configuración
    • Polimorfismo
    • Remplazo de componentes
    • Adherir a protocolos

Cambios semánticos. Si la semántica de lo que hacemos cambia, el modulo que lo implementa también cambiara. Se relaciona con el sentido. Cambia la lógica.
Cambios sintéticos. Cambios en la secuencia de lo que se hace. Los cambios de “Mantener la interfaz” funcionan aquí. Se relaciona con la estructura.

semantico: que se relaciona con el sentido
sintactico: que se relaciona con la estructura

COMPLETO:
Familias de tácticas:
1.- Confinar modificaciones. Las tácticas van a intentar trabajar sobre nuestros módulos para que cada cambio que nos pidan esté confinado a sólo un módulo. Cuando logramos esto logramos que las dependencias entre módulos sean más ligeras y el cambio que nos proponen no afecte a muchas partes del sistema.
a) Coherencia semántica. Habla de la relación entre las responsabilidades de los módulos. Hablamos de acoplamiento y cohesión. Si logramos encontrar la cohesión en un módulo entonces vamos a poder hacer que ese módulo sea más mantenible. De lo contrario es posible que ese módulo cambie por diferentes razones.
Abstraer servicios comunes. Cuando encontramos que la aplicación tiene servicios más genéricos de no necesario podemos abstraerlos a un punto común y que las dependencias vayan de los módulos cohesivos a un servicio o modulo externo.
b) Generalizar. Al generalizar un módulo podemos separar lo específico de lo genérico.
c) Limitar opciones disponibles. Limitar el rango de modificación nos ayuda a que sea más mantenible.
d) Anticipar cambios. Prepararnos para algún cambio que nosotros mismo sepamos que se deberá de dar en el futuro tomando en cuenta una estrategia sobre como incorporar el nuevo cambio. Los patrones de diseño suelen estar orientados a esto (Patrón estrategia).
2.- Prevenir efectos domino. Trabaja estrictamente con las dependencias, es decir cuando podemos detectar que un cambio generaría problemas en otros módulos o dependencias.
Prevenir efectos dominó. Trabaja estrictamente con las dependencias. Es decir, cuándo podemos detectar que un cambio generaría problemas en otros módulos u otras dependencias.
• Ocultar información. Cualquier módulo u objeto que diseñemos, tenga la capacidad de ocultar cierta parte de la información para que los agentes externos no dependan de esa información puntual sino de una interfaz clara que no puedan cambiar por más que la información cambie. De esta forma podemos garantizar que, si el cambio de la información es importante, los dependientes no necesiten cambiar porque están pasando por una interfaz que no cambió.
• Mantener la interfaz. Si tengo un servicio que hace algo, la dependencia a ese servicio va a ser a través de una interfaz clara, de lo contrario cualquier acción cuándo cambie puede poner en riesgo el módulo.
• Restringir comunicación. Para generar sistemas que estén acoplados de forma ligeras, en vez de conocer las dependencias de tus dependencias, siempre te limites a tus dependencias directas, de esta forma cualquier cambio en la forma que tus dependencias trabajan no afecta al módulo en el que estás trabajando.
• Intermediarios. Hablamos de un punto dónde podamos compatibilizar a un módulo con otro y si dejan de ser compatibles, estos intermediarios puedan servir como punto de compatibilidad.
3.- Diferir enlace. Habla sobre cómo podemos hacer para que un cambio en nuestro código no requiera desplegar toda la aplicación completa.
• Registro en ejecución. Cuando un módulo o servicio depende de otro, si dependen fuertemente van a requerir estar compilados juntos. Si nosotros podemos diferir esa compilación y que se registre un servicio en momento de ejecución, es decir que se ponga disponible a sus dependencias en el momento de ejecución, podemos hacer que estos servicios se puedan desplegar independientemente.
• Archivos de configuración. Van a servir para en momento de ejecución saber cómo conectar varias partes. Es imprescindible que nuestros módulos dependan de interfaces y no de implementaciones específicas.
• Polimorfismos. Un objeto pueda comportarse de forma diferente en base a su estado. A través del polimorfismo podemos postergar la forma en que se resuelve un problema dependiendo de qué instancia del objeto será.
• Reemplazo de componentes. Tener la capacidad de desplegar un componente y luego desplegar su reemplazo, o quizás otro componente que respete esa interfaz, y que todo el resto de nuestra aplicación no necesite cambiar.
• Adherir a protocolos. Nos permite tener un protocolo claro entre dos módulos y no necesitar saber la instancia específica o el tipo específico de un módulo.

Estos temas son un resumen de lo expuesto en este modulo…

 -------------------------------------------------
*)PRINCIPIOS GRASP
  +Encapsulamiento
  +Acoplamiento
  +Cohesion
  +Ley Demeter
  +Separation of Concerns
  +Invertion of Control
  +Don't Repeate Yourself
  +Keep it Simple Stupid
 -------------------------------------------------
*)PRINCIPIOS SOLID
  +Single Responsability Principal
  +Open/Closed Principal
  +Liskov Sustitution Principal
  +Interface Segregation Principal
  +Dependention Invertion Principal
 -------------------------------------------------
*)PATRONES ARQUITECTONICOS
  +Circuit Breaker
  +Publisher/Suscriber
  +Dashboard
  +Plugins
 -------------------------------------------------
*)PATRONES DISEÑO SOFTWARE
  ->CREACIONALES<-
  +Singleton
  +Prototype
  +Builder
  +Factory Method
  +Abstract Factory
  +Object Pool
  ->ESTRUCTURALES<-
  +Adapter
  +Bridge
  +Composite
  +Decorator
  +Facade
  +Flyweight
  +Proxy
->COMPORTAMIENTO<-
  +Iterator
  +Command
  +Observer
  +Tempalte Method
  +Strategy
  +Chain of Responsability
  +Interpreter
  +Mediator
  +Moment
  +Null Object
  +State
  +Visitor
 -------------------------------------------------
<h3>Prevenir efectos Domino:</h3>

Los cambios provocan otros cambios no previstos en el sistema.
Tácticas:

  • Ocultar Información
  • Mantener la Interfaz
  • Restringir Comunicación
  • Intermediarios
<h3>Diferir enlace:</h3>
  • Registro en ejecución
  • Archivos de Configuración
  • Polimorfismo
  • Reemplazo de Componentes
  • Adherir a Protocolos

Cuando hablamos de ocular información hablamos de encapsulamiento? Por ejemplo

### Adherencia a Protocolos #### Definición Utilización de protocolos de comunicación estandarizados para el intercambio de información entre módulos, permitiendo que evolucionen independientemente mientras respeten el contrato establecido. #### Protocolos Comunes * REST, GraphQL para APIs web * gRPC, Thrift para comunicación entre servicios * AMQP, Kafka para mensajería * JSON, XML, Protocol Buffers para serialización #### Beneficios * Desacopla productores y consumidores de servicios * Facilita la evolución independiente de componentes * Mejora la interoperabilidad entre sistemas heterogéneos * Simplifica la integración con sistemas de terceros #### Buenas Prácticas * Versionado explícito de APIs * Documentación detallada (OpenAPI, Swagger) * Compatibilidad hacia atrás cuando sea posible * Diseño de contratos centrado en el dominio, no en la implementación
### Prevenir Efectos Dominó Objetivo: Evitar que un cambio en un módulo cause una cascada de cambios en otros módulos del sistema. #### a) Ocultar Información * **Definición mejorada**: Implementar encapsulación para que los módulos externos dependan solo de interfaces estables y no de detalles de implementación. * **Beneficios**: * Reduce dependencias entre módulos * Permite cambios internos sin afectar a los consumidores * Simplifica el mantenimiento a largo plazo * **Ejemplo práctico**: Un módulo de cálculo de impuestos que expone métodos públicos estables mientras los algoritmos internos pueden cambiar según nuevas regulaciones. * **Principio relacionado**: Encapsulación en programación orientada a objetos. #### b) Mantener Interfaces Estables * **Definición mejorada**: Definir claramente cómo otros componentes interactúan con un módulo mediante un conjunto consistente de funciones. * **Técnicas**: * Contratos de interfaz bien definidos * Versiones de API para cambios significativos * Uso del patrón Fachada para unificar puntos de acceso * **Beneficio clave**: Permite actualizar implementaciones internas sin afectar a los clientes del servicio. * **Ejemplo**: Añadir pasos adicionales a un proceso interno mientras se mantiene la misma firma de método en la interfaz pública. #### c) Uso de Intermediarios * **Definición mejorada**: Implementar componentes que actúen como puentes entre módulos incompatibles o que puedan cambiar independientemente. * **Patrones aplicables**: * Patrón Fachada (FACADE): Simplifica interfaces complejas * Patrón Proxy: Controla acceso a objetos * Patrón Adaptador (ADAPTER): Convierte interfaces incompatibles * **Beneficios**: * Gestiona cambios en interfaces sin propagar efectos * Facilita la evolución independiente de componentes * Mejora la testabilidad de los módulos #### d) Aplicar la Ley de Demeter (Complemento) * **Definición**: Principio de mínimo conocimiento - un objeto debe tener conocimiento limitado sobre otros objetos. * **Regla práctica**: Un método de un objeto debe invocar solo: * Métodos del propio objeto * Métodos de parámetros pasados al método * Métodos de objetos creados dentro del método * Métodos de componentes directos del objeto

⭐️ Excelente ⭐️

⭐️⭐️⭐️⭐️⭐️