Diseño de arquitecturas .NET orientadas a microservicios
3/5
()
Información de este libro electrónico
Gracias a este libro, dejará atrás los contratiempos al trabajar con monolitos, como el alto acoplamiento dentro de un mismo sistema o la baja escalabilidad al resolver con la misma arquitectura distintos problemas. Asimismo, aprenderá alternativas que le permitirán aplicar distintas soluciones a multitud de cuestiones y sabrá distinguir cuándo es mejor orientar su arquitectura a microservicios y cuándo mantener su monolito.
1.Conocerá los fundamentos de desarrollo .NET.
2.Construirá cada módulo de que se compone una arquitectura con .NET.
3.Aplicará seguridad a su arquitectura mediante la autenticación y autorización JWT.
4.Sabrá cuándo aplicar una arquitectura monolítica o una orientada a microservicios.
5.Será capaz de modelar arquitecturas limpias cumpliendo la regla de dependencia.
6.Diseñará una arquitectura de microservicios usando distintas tecnologías en cada una.
7.Aprenderá los distintos tipos de comunicación entre microservicios.
Además, tras su lectura, conseguirá emplear una arquitectura limpia que le permitirá abstrae del almacén de datos utilizado, separar responsabilidades, crear un código reutilizable y mantenible, dotar a su sistema de un nivel de seguridad basado en token JWT, aprender los patrones más utilizados, así como conocer las bondades del desarrollo .NET, entre muchas otras posibilidades.
Es el momento de dar rienda suelta a su creatividad y convertirse en el mejor arquitecto de software. Hágase con el libro, conozca los beneficios que aporta utilizar este tipo de arquitecturas y decida por sí mismo si debe o no aplicarlo.
Ramón Serrano Valero: Ingeniero Informático con un máster en Ingeniería de Desarrollo para Dispositivos Móviles y otro en Ciencia de Datos. A lo largo de sus más de 14 años de experiencia en desarrollo .NET, diseñando diferentes arquitecturas software para las distintas necesidades de los clientes y asesorando a otras empresas en la definición de arquitecturas, ha aprendido que no todas las empresas requieren una misma arquitectura y que, en ocasiones, no realizar una sobre ingeniería simplifica la solución, al evitar que crezca su complejidad más de lo necesario.
Relacionado con Diseño de arquitecturas .NET orientadas a microservicios
Libros electrónicos relacionados
Guía práctica de Kubernetes: Proyectos para crear aplicaciones de éxito con Kubernetes Calificación: 0 de 5 estrellas0 calificacionesAprende a Programar ASP .NET y C# - Segunda Edición Calificación: 0 de 5 estrellas0 calificacionesDiseño de Software Calificación: 0 de 5 estrellas0 calificacionesAprende a Desarrollar con Spring Framework Calificación: 3 de 5 estrellas3/5Desarrollo de Software Calificación: 0 de 5 estrellas0 calificacionesEl Libro Práctico Del Programador Ágil Calificación: 5 de 5 estrellas5/5Programación en Go Calificación: 5 de 5 estrellas5/5AngularJS: Conviértete en el profesional que las compañías de software necesitan. Calificación: 4 de 5 estrellas4/5UF2406 - El cliclo de vida del desarrollo de aplicaciones Calificación: 0 de 5 estrellas0 calificacionesAprende a Modelar Aplicaciones con UML Calificación: 1 de 5 estrellas1/5Aprende a Programar en ASP .NET y C# Calificación: 0 de 5 estrellas0 calificacionesIngeniería y Arquitectura del Software Calificación: 0 de 5 estrellas0 calificacionesAprender Docker, un enfoque práctico Calificación: 5 de 5 estrellas5/5Conexión SQL SERVER & C# (Manual para principiantes) Calificación: 1 de 5 estrellas1/5Metodologías ágiles para el desarrollo de software Calificación: 0 de 5 estrellas0 calificacionesLegacy Code Calificación: 0 de 5 estrellas0 calificacionesAndroid: Programación de dispositivos móviles a través de ejemplos Calificación: 0 de 5 estrellas0 calificacionesDe qué hablo cuando hablo de programar (volumen 2) Calificación: 0 de 5 estrellas0 calificacionesCurso de Programación y Análisis de Software - 2ª Edición Calificación: 0 de 5 estrellas0 calificacionesBackbone JS Calificación: 0 de 5 estrellas0 calificacionesDe qué hablo cuando hablo de programar (volumen 1) Calificación: 4 de 5 estrellas4/5El Libro Negro del Programador Calificación: 4 de 5 estrellas4/5HTML5 Avanzado Calificación: 0 de 5 estrellas0 calificacionesSQL Server 2014 Soluciones prácticas de administración: Software para bases de datos Calificación: 5 de 5 estrellas5/5Curso de Ingeniería de Software Calificación: 4 de 5 estrellas4/5Estructuras de datos y algoritmos fundamentales Calificación: 0 de 5 estrellas0 calificacionesCómo construir Microservicios : Los diez principales trucos para modelar, integrar y desplegar microservicios Calificación: 4 de 5 estrellas4/5Automatización de Tests de Software Con Selenium Calificación: 0 de 5 estrellas0 calificacionesAprender React con 100 ejercicios prácticos Calificación: 0 de 5 estrellas0 calificacionesDesarrollo Web en Java Calificación: 3 de 5 estrellas3/5
Programación para usted
Aprende a programar: Crea tu propio sitio web Calificación: 4 de 5 estrellas4/5Excel de la A a la Z: El Manual Práctico Paso a Paso de Microsoft Excel para Aprender Funciones Básicas y Avanzadas, Fórmulas y Gráficos con Ejemplos Fáciles y Claros Calificación: 0 de 5 estrellas0 calificacionesPython para principiantes Calificación: 5 de 5 estrellas5/5Python Paso a paso: PROGRAMACIÓN INFORMÁTICA/DESARROLLO DE SOFTWARE Calificación: 4 de 5 estrellas4/5GuíaBurros Microsoft Excel: Todo lo que necesitas saber sobre esta potente hoja de cálculo Calificación: 4 de 5 estrellas4/5HTML para novatos Calificación: 5 de 5 estrellas5/5Ortografía para todos: La tabla periódica de la ortografía Calificación: 5 de 5 estrellas5/5El gran libro de Python Calificación: 5 de 5 estrellas5/5Fundamentos de programación: un enfoque práctico Calificación: 5 de 5 estrellas5/5Lógica de programación: Solucionario en pseudocódigo – Ejercicios resueltos Calificación: 4 de 5 estrellas4/5Linux Essentials: una guía para principiantes del sistema operativo Linux Calificación: 5 de 5 estrellas5/5VBA Excel Guía Esencial Calificación: 5 de 5 estrellas5/5Python Aplicaciones prácticas Calificación: 4 de 5 estrellas4/5Fundamentos De Programación Calificación: 5 de 5 estrellas5/5Python a fondo Calificación: 5 de 5 estrellas5/5Arduino. Trucos y secretos.: 120 ideas para resolver cualquier problema Calificación: 5 de 5 estrellas5/5Arduino. Edición 2018 Curso práctico Calificación: 4 de 5 estrellas4/5Curso básico de Python: La guía para principiantes para una introducción en la programación con Python Calificación: 0 de 5 estrellas0 calificacionesAprende a programar en C# Calificación: 5 de 5 estrellas5/5Diseño Web con CSS Calificación: 5 de 5 estrellas5/5El Libro Práctico Del Programador Ágil Calificación: 5 de 5 estrellas5/5115 Ejercicios resueltos de programación C++ Calificación: 3 de 5 estrellas3/5Introducción al Uso de Formularios (UserForms) en VBA Calificación: 3 de 5 estrellas3/5JavaScript: Guía completa Calificación: 4 de 5 estrellas4/5Bases de Datos con MySQL Calificación: 4 de 5 estrellas4/5Power Query para Excel 365/2021 Calificación: 0 de 5 estrellas0 calificacionesAprende a Programar en C++ Calificación: 5 de 5 estrellas5/5Aprender a programar con Excel VBA con 100 ejercicios práctico Calificación: 5 de 5 estrellas5/5
Comentarios para Diseño de arquitecturas .NET orientadas a microservicios
1 clasificación0 comentarios
Vista previa del libro
Diseño de arquitecturas .NET orientadas a microservicios - Ramón Serrano Valero
PRINCIPIOS SOLID
Hemos ido introduciendo el concepto sin haber entrado en detalle, pero estos principios son bien conocidos y existe mucha literatura al respecto, que debemos leer. Los principios SOLID fueron una de las aportaciones del ingeniero de software Robert Cecil Martin, también conocido como Uncle Bob
a la comunidad de artesanos del software, una serie de principios de diseño orientado a objetos, que todo desarrollador debería conocer y aplicar.
Veamos una serie de ejemplos de implementación en .NET Core 5 y lenguaje C#, para llegar a entender mejor como aplicar estos principios en el mundo real.
•SRP: Principio de responsabilidad única
•OCP: Principio abierto/cerrado
•LSP: Principio de sustitución Liskov
•ISP: Principio de segregación de interfaz
•DIP: Inversión de Dependencias
Procede de uno de los principios de diseño orientado a objetos, basado en el desacoplamiento. En él se establece que módulos de nivel superior no deberían depender de otros de nivel inferior, sino que ambos deberían depender de abstracciones, es lo que se conoce como bajo acoplamiento, cuanto menor, mejor.
Dicho de otro modo, las clases deberían desentenderse de la implementación concreta de una clase. ¿Cómo? Sirviéndose de abstracciones o interfaces haciendo uso de la inyección de dependencias.
Esta definición en la teoría queda genial; sin embargo, hasta que no veamos un ejemplo práctico, costará comprenderlo.
S: Principio de responsabilidad única (SRP)
Es el primer principio de SOLID, en el que se defiende que una clase únicamente debe representar una única responsabilidad; para Robert C. Martin: Una clase únicamente debe tener una razón para cambiar
.
Es decir, no deberíamos tener una clase que realiza más de una acción, ¿cómo podemos lograr no infringir este principio?
•Cuando encontremos más de un método público en la misma clase, es muy probable que dicha clase tenga más de una responsabilidad.
•Cuando existan varios atributos de una clase en el que unos pocos siempre sean utilizados por una clase y el resto por otra distinta, esto implica que dicha clase podría haberse dividido en otras dos, separando responsabilidades.
•Dificultad de testing sobre el método de una clase, puede causar que el método deba segmentarse.
Una vez consigamos separar por responsabilidades, nuestro código incrementará la reutilización, pudiendo invocar desde múltiples servicios estas funcionalidades.
Al tener clases más pequeñas, que únicamente realizan una responsabilidad, conseguimos reducir la duplicidad del código y ganamos en legibilidad, ¿no es genial?
Veamos un ejemplo donde se infringe este principio [S5.3]; Tenemos una clase llamada UserRepositorySrpViolation, que podemos observar en la línea 5 del código. Esta clase posee dos métodos públicos, uno para registrar el usuario y otro método para enviar un email de bienvenida al usuario que se acaba de registrar.
De modo que, tras registrar el usuario de manera satisfactoria en la base de datos, automáticamente se envía un email.
IllustrationFigura S5.3
IllustrationFigura S5.3.a
Al disponer de dos métodos públicos en la misma clase, tenemos dos puntos de entrada a la clase y por tanto dos posibles responsabilidades, ello conduce al incumplimiento del principio [S5.3.a]. Pero…entonces… ¿existe alguna manera de evitar esto?
La respuesta, como no podía ser de otra manera, es sí. Simplemente intentemos separar [S5.4] de la clase UserRepository el método que no pertenece al propio dominio de usuario, es decir, el envío de email SendWelcomeMessageToMail.
IllustrationFigura S5.4
Para ello creamos una nueva clase notificadora de emails EmailSenderWelcomeMessage, que seguirá teniendo el mismo método antiguo de envío de emails.
Posteriormente, en la clase UserRepository inyectamos la clase notificadora de emails que acabamos de crear a través de su constructor; de esta forma, podremos invocar el método de la instancia _emailSenderWelcomeMessage, por lo que seguiremos enviando el mismo email tras el registro de usuario.
IllustrationFigura S5.4.a
Con esto hemos conseguido que UserRepository [S5.4.a] tenga una cohesión más alta y con una única responsabilidad. Por lo que ganamos en desacoplamiento.
¿Y cuál es la diferencia? La diferencia principal es que ahora ambas clases tienen una única responsabilidad, la clase repositorio de usuario únicamente posee un método de entrada y la clase envío de email también, con lo cual ganamos en legibilidad, testeo y reutilización, es decir, ambas clases tienen que hacer lo que han de hacer y nada más.
Pero podemos ir un paso más allá y ganar en modularidad, la posibilidad de que varias clases puedan implementar el mismo método que defina su interfaz [S5.5].
IllustrationFigura S5.5
Para ello, creamos una interfaz ISender, que implemente un método SendTo, así como dos clases SendWelcomeMessageByPushNotification, que envía una notificación push al móvil y SendWelcomeMessageByEmail, que envía un email al usuario registrado.
Ambas clases implementan la interfaz ISender, lo cual nos permite ganar en modularidad y que podamos crear tantos tipos de mensajería como queramos, ya que cada clase implementará su forma de comunicación.
Ahora ya únicamente en la clase UserRepositoryModular recibiremos por parámetro en el constructor una clase que implemente dicha interfaz, con lo cual, si le proporcionásemos la clase de envío de emails, la línea 17 de UserRepositoryModular, implementaría el envío definido en la clase SendWelcomeMessageByEmail; no obstante, si por el contrario, se inyectase la clase de notificaciones push, la línea 17, implementaría el envío push mediante el método SendTo. ¿Increíble las ventajas que puede traernos la modularidad?
O: Principio abierto/cerrado (OCP)
Este principio establece que nuestras clases deben ser abiertas para extensión, pero cerradas para modificación.
Uno de los principales motivos es no romper
aquello que ya funcionaba, por el simple hecho de haber introducido una nueva funcionalidad o simplemente cambio sobre la clase en cuestión.
No cumplir este principio puede hacer que nuestro equipo de desarrollo entre en bucle de regresión tratando de probar casos de uso que con anterioridad al cambio las pruebas pasaban y posteriormente debemos volver a probarlas.
Para no infringir este principio, la clave es evitar la dependencia de concreciones, es decir, clases concretas, abstraernos de su implementación. No modificar una clase ya implementada, se debe hacer extensible mediante la herencia, empleando para ello abstracciones como clases abstractas o interfaces.
En otras palabras, no dependa en la implementación del método de una clase, de un tipo en concreto, dado que, si un día cambia su tipo o simplemente incorporamos uno nuevo, nos veríamos obligados a introducir múltiples condicionales if else
o un switch case
y, por tanto, estaríamos modificando la implementación del método incumpliendo el principio.
Si conseguimos desarrollar desacoplando los métodos de la clase, de una implementación concreta, podremos incorporar nuevos casos de uso al extender su funcionalidad.
Veamos con un ejemplo cómo se incumple este principio [S5.6]; disponemos de una tienda virtual, representada por la clase VirtualShop, que vende productos, inicialmente únicamente vendía bicicletas, representada por la clase BikePriceCalculator, de modo que se implementó proporcionando la concreción BikePriceCalculator como parámetro del método, para posteriormente realizar el cálculo del IVA del producto en sí, invocando su método CalculatePrice().
IllustrationFigura S5.6
Posteriormente, la tienda virtual creció y vendía también otros productos como neumáticos para bicicletas, así que decidió crear un producto nuevo, WheelPriceCalculator [S5.7], para tal propósito.
IllustrationFigura S5.7
Sin embargo, para que la clase VirtualShop pudiera calcular el nuevo precio del producto, al haber dependido de la concreción del producto bicicleta, nos vemos obligados a modificar dicho método porque no es capaz el método CalculateProductPrice de extender la funcionalidad para incorporar el nuevo producto sin modificar el método.
Para solucionar el problema debemos depender de interfaces o clases abstractas, de modo que modifiquemos la clase de tienda virtual VirtualShopOCP para que sea abierta a extensión [S5.8].
Para ello creamos la interfaz IShopProduct, declarando el método público de cálculo de precio. Posteriormente, las clases que teníamos de BikePriceCalculatorOCP, clase del producto bici y WheelPriceCalculatorOCP, clase del producto neumático, haremos que implementen ambos el método de la interfaz IShopProduct.
Por último, cambiamos el parámetro de entrada del método de cálculo, CalculateProductPrice, que emplea la tienda, por una clase que cumpla la interfaz.
IllustrationFigura S5.8
De esta forma, si un día queremos incorporar un nuevo producto para calcular su precio en tienda, bastará con crear una nueva clase para el nuevo tipo de producto, que implemente la interfaz IShopProduct. Con esto conseguimos que nuestra clase esté abierta a