Saltear al contenido principal

SOLID El principio de responsabilidad única – Tutoriales Java

[ad_1]

SOLID es uno de los conjuntos de principios de diseño más populares en el desarrollo de software orientado a objetos. Es un acrónimo mnemónico de los siguientes cinco principios de diseño:

Todos son ampliamente utilizados y vale la pena conocerlos. Pero en esta primera publicación de mi serie sobre principios SÓLIDOS, me enfocaré en el primero: el principio de responsabilidad única.

Robert C. Martin lo describe como:

Una clase debe tener una, y solo una, razón para cambiar.

Incluso si nunca ha oído hablar de Robert C. Martin o de sus libros populares, probablemente haya oído hablar de este principio y lo haya utilizado. Es uno de los principios básicos que la mayoría de los desarrolladores aplican para crear software robusto y fácil de mantener. Puede aplicarlo no solo a clases, sino también a componentes de software y microservicios.

Beneficios del principio de responsabilidad única

Abordemos las preguntas más importantes antes de profundizar en este principio de diseño: ¿Por qué debería usarlo y qué sucede si lo ignora?

El argumento a favor del principio de responsabilidad exclusiva es relativamente simple: hace que su software sea más fácil de implementar y evita efectos secundarios inesperados de cambios futuros.

signo que indica opciones

Frecuencia y efectos de los cambios

Todos sabemos que los requisitos cambian con el tiempo. Cada uno de ellos también cambia la responsabilidad de al menos una clase. Cuantas más responsabilidades tenga su clase, más tendrá que cambiarla. Si su clase implementa múltiples responsabilidades, ya no son independientes entre sí.

Debe cambiar de clase tan pronto como cambie una de sus responsabilidades. Obviamente, esto sucede con más frecuencia de la que necesitaría cambiar si tuviera una sola responsabilidad.

Esto puede no parecer un gran problema, pero también afecta a todas las clases o componentes que dependen de la clase modificada. Dependiendo de su movimiento, es posible que deba actualizar las dependencias o volver a compilar las clases dependientes, aunque no se ven directamente afectadas por su movimiento. Usan solo una de las otras responsabilidades implementadas por su clase, pero debe actualizarlas de todos modos.

Al final, necesitas cambiar de clase con más frecuencia, y cada cambio es más complicado, tiene más efectos secundarios y requiere mucho más trabajo del que debería. Por lo tanto, es mejor evitar estos problemas asegurándose de que cada clase tenga una sola responsabilidad. Además, si desea comprender mejor lo que sucede en su aplicación, puede utilizar la solución de creación de perfiles de código de Retrace.

Más fácil de entender

El principio de responsabilidad exclusiva proporciona otro beneficio sustancial. Las clases, los componentes de software y los microservicios que tienen una sola responsabilidad son mucho más fáciles de explicar, comprender e implementar que los que brindan una solución para todo. Esto reduce la cantidad de errores, mejora la velocidad de desarrollo y hace que su vida como desarrollador de software sea mucho más fácil.

confusión de signo de interrogación

Sin embargo, asegúrese de no simplificar demasiado su código. Algunos desarrolladores llevan el principio de responsabilidad única al extremo, creando clases con una sola función. Más tarde, cuando quieran escribir algún código real, tendrán que inyectar muchas dependencias, lo que hace que el código sea muy ilegible y confuso.

Por lo tanto, el principio de responsabilidad exclusiva es una regla importante para que su código sea más comprensible, pero no lo use como su Biblia de programación. Utilice el sentido común al desarrollar código. No tiene sentido tener varias clases que contengan solo una función.

Una simple pregunta para validar tu proyecto

Desafortunadamente, seguir el principio de responsabilidad exclusiva parece mucho más fácil de lo que suele ser.

Si crea su software por un período más largo y necesita adaptarlo a los requisitos cambiantes, puede parecer que el enfoque más fácil y rápido es agregar un método o funcionalidad al código existente en lugar de escribir una nueva clase o componente. Pero esto suele dar lugar a clases con más responsabilidad y hace que sea cada vez más difícil mantener el software.

Puede evitar estos problemas haciendo una pregunta simple antes de realizar cualquier cambio: ¿Cuál es la responsabilidad de su clase / componente / microservicio?

Si su respuesta incluye la palabra «e», probablemente esté violando el principio de responsabilidad exclusiva. Por lo tanto, es mejor dar un paso atrás y repensar su enfoque actual. Probablemente haya una mejor manera de implementarlo.

botones de caja registradora antigua

Para dar un ejemplo más concreto, suponga que tenemos una clase para un empleado que contiene métodos para calcular y reportar su salario. En otras palabras, el cálculo de salarios se puede clasificar como lectura de datos y manipulación posterior.

Mientras que el salario de informe es una operación de persistencia de datos, donde los datos se almacenan en algún medio de almacenamiento. Si seguimos el principio de responsabilidad exclusiva de Martin, estas clases deberían dividirse, ya que las funciones comerciales son bastante diferentes.

A continuación, examinaremos algunos ejemplos de Java de la vida real sobre el principio de responsabilidad exclusiva.

Ejemplos del mundo real del principio de responsabilidad exclusiva

Puede encontrar muchos ejemplos de todos los principios de diseño SÓLIDOS en software de código abierto y en la mayoría de las aplicaciones bien diseñadas. Como su capa de persistencia de Java y las estructuras y especificaciones populares, que probablemente utilizó para implementarla.

Una es la especificación Java Persistence API (JPA). Tiene una, y solo una, responsabilidad: definir una forma estandarizada de administrar datos persistentes en una base de datos relacional utilizando el concepto de mapeo relacional de objetos.

Ésta es una gran responsabilidad. La especificación define muchas interfaces diferentes para ella, especifica un conjunto de estados en el ciclo de vida de la entidad y las transiciones entre ellos, y también proporciona un lenguaje de consulta, llamado JPQL.

Pero esa es la responsabilidad exclusiva de la especificación JPA. Otras funciones que pueda necesitar para implementar su aplicación, como la validación, las API REST o el registro, no son responsabilidad de JPA. Debe incluir otras especificaciones o marcos que brinden estas características.

Si profundiza un poco más en la especificación JPA, puede encontrar aún más ejemplos del principio de responsabilidad exclusiva.

EntityManager de JPA

La interfaz EntityManager proporciona un conjunto de métodos para conservar, actualizar, eliminar y leer entidades de una base de datos relacional. Su responsabilidad es administrar las entidades que están asociadas con el contexto de persistencia actual.

Esta es la única responsabilidad de EntityManager. No implementa ninguna lógica empresarial ni validación o autenticación de usuarios. Incluso el modelo de dominio específico de la aplicación, que utiliza anotaciones definidas por la especificación JPA, no pertenece a EntityManager. Por lo tanto, solo cambia si cambian los requisitos del concepto general de persistencia.

Convertidor de atributos JPA

La responsabilidad de EntityManager puede ser demasiado grande para servir como un ejemplo fácilmente comprensible del principio de responsabilidad única. Entonces, echemos un vistazo a un ejemplo más pequeño: un AttributeConverter según lo definido por la especificación JPA.

La responsabilidad de un AttributeConverter es pequeña y fácil de entender. Convierte un tipo de datos utilizado en su modelo de dominio en uno que su proveedor de persistencia puede conservar en la base de datos. Puede usarlo para conservar tipos de datos no admitidos, como su clase de valor favorita, o para personalizar la asignación de un tipo de datos admitido, como una asignación personalizada a valores de enumeración.

Aquí hay un ejemplo de un AttributeConverter que mapea un objeto java.time.Duration, que no es compatible con JPA 2.2, a un java.lang.Long: La implementación es rápida y fácil. Necesita implementar esta interfaz AttributeConverter y anotar su clase con una anotación en> @Converter

@Converter(autoApply = true) 
public class DurationConverter implements AttributeConverter<Duration, Long> { 
    @Override 
    public Long convertToDatabaseColumn(Duration attribute) { 
      return attribute.toNanos(); 
    }   

    @Override 
    public Duration convertToEntityAttribute(Long duration) { 
        return Duration.of(duration, ChronoUnit.NANOS); 
    } 
}

Como puede ver en el ejemplo de código, DurationConverter implementa solo las dos operaciones de conversión necesarias. El método convertToDatabaseColumn convierte el objeto Duration en un Long, que se conservará en la base de datos. Y convertToEntityAttribute implementa la operación inversa.

La simplicidad de este fragmento de código muestra los dos beneficios principales del principio de responsabilidad única. Al limitar la responsabilidad de DurationConverter a la conversión entre los dos tipos de datos, su implementación se vuelve fácil de entender y solo cambiará si se cambian los requisitos del algoritmo de mapeo.

Repositorio de datos de Spring

El último ejemplo del que hablar es el repositorio de Spring Data. Implementa el estándar de repositorio y proporciona una funcionalidad común para crear, actualizar, eliminar y leer operaciones. El repositorio agrega una abstracción en la parte superior de EntityManager para facilitar el uso de JPA y reducir el código necesario para estas funciones de uso frecuente.

Puede definir el repositorio como una interfaz que amplía una interfaz estándar de Spring Data, por ejemplo, Repository, CrudRepository o PagingAndSortingRepository. Cada interfaz proporciona un nivel diferente de abstracción y Spring Data la usa para generar clases de implementación que brindan la funcionalidad necesaria.

bobina de resorte de metal

El fragmento de código a continuación muestra un ejemplo simple de tal repositorio. AuthorRepository extiende la interfaz Spring CrudRepository y define un repositorio para una entidad Author que usa un atributo de tipo Long como clave principal.

interface AuthorRepository extends CrudRepository<Author, Long> { 
    List findByLastname(String lastname); 
}

CrudRepository de Spring proporciona operaciones CRUD estándar, como un método de guardar y eliminar para operaciones de escritura y los métodos findById y findAll para recuperar una o más entidades Author de la base de datos.

AuthorRepository también define el método findByLastName, para el cual Spring Data genera la consulta JPQL requerida para seleccionar las entidades Autor por su atributo de apellido.

Cada repositorio agrega implementaciones listas para usar de las operaciones más comunes para una entidad específica. Esta es la responsabilidad exclusiva de este repositorio.

Al igual que el EntityManager descrito anteriormente, el repositorio no es responsable de la validación, autenticación o implementación de ninguna lógica empresarial. Tampoco es responsable de ninguna otra entidad. Esto reduce la cantidad de cambios necesarios y hace que cada repositorio sea fácil de comprender e implementar.

Currículo

El principio de responsabilidad exclusiva es uno de los principios de diseño más utilizados en la programación orientada a objetos. Puede aplicarlo a clases, componentes de software y microservicios.

Para seguir este principio, su clase no puede tener más de una responsabilidad, por ejemplo, administrar entidades o convertir tipos de datos. Esto evita cualquier acoplamiento técnico innecesario entre responsabilidades y reduce la probabilidad de que deba cambiar de clase. También disminuye la complejidad de cada cambio porque reduce el número de clases dependientes que se ven afectadas por él. Sin embargo, sea razonable.

No es necesario tener varias clases, todas con una sola función. Trate de encontrar el equilibrio adecuado al definir responsabilidades y clases.

Leer más: Obtenga una introducción a los conceptos de OOP en Java y aprenda sobre los 4 conceptos principales: abstracción, encapsulación, herencia y polimorfismo.

Asegúrese de registrarse en Retrace. Retrace ayuda a los desarrolladores a mejorar el rendimiento de sus aplicaciones, detectar errores e incluso puede decirle cómo mejorar su código. Actualmente puede hacer uso de una prueba gratuita para conocer sus nuevas funciones.

[ad_2]


El principio de responsabilidad única - Stackify

Esta entrada tiene 0 comentarios

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Volver arriba