
Me encuentro con frecuencia desarrolladores que no han oído hablar de los principios SOLID (hemos . — Nota del editor) o de la programación orientada a objetos (POO), o han oído sobre ellos pero no los aplican en la práctica. Este artículo describe las ventajas de los principios de la POO que ayudan al desarrollador en su trabajo diario. Algunos son bien conocidos, otros no tanto, así que el artículo será útil tanto para principiantes como para programadores experimentados.
Recordamos: Para todos los lectores de «Habr» — descuento de 10,000 rublos al inscribirse en cualquier curso de Skillbox con el código promocional «Habr».
Skillbox recomienda: Curso en línea educativo .
DRY (No te repitas)
Un principio bastante simple, cuya esencia es clara por su nombre: «No te repitas». Para un programador, esto significa la necesidad de evitar código duplicado, así como la posibilidad de utilizar abstracción en su trabajo.
Si hay dos fragmentos repetidos en el código, deben combinarse en un solo método. Si un valor fijo se utiliza más de una vez, debe convertirse en una constante pública.
Esto es necesario para simplificar el código y facilitar su mantenimiento, que es el objetivo principal de la POO. Sin embargo, tampoco se debe abusar de la combinación, ya que el mismo código no puede pasar la verificación tanto con OrderId como con SSN.
Encapsulamiento de cambios
Los productos de software de la mayoría de las empresas están en constante evolución. Por lo tanto, es necesario realizar cambios en el código y mantenerlo. Puedes simplificar tu vida mediante el encapsulamiento. Esto permitirá probar y mantener de manera más efectiva la base de código existente. .
Si estás programando en Java, .
Principio de apertura/cierre
Este principio se puede recordar fácilmente al leer la siguiente afirmación: «Las entidades de software (clases, módulos, funciones, etc.) deben estar abiertas a la extensión, pero cerradas a la modificación». En la práctica, esto significa que pueden permitir cambios en su comportamiento sin modificar el código fuente original.
El principio es importante cuando los cambios en el código fuente requieren revisiones, pruebas unitarias y otros procedimientos. El código que se adhiere al principio de apertura/cierre no se modifica al ser ampliado, por lo que presenta muchos menos problemas.
Aquí hay un ejemplo de código que viola este principio.

Si se necesita cambiar algo, tomará mucho tiempo, ya que habrá que modificar todas las secciones del código relacionadas con el fragmento necesario.
Por cierto, la apertura y el cierre son uno de los principios SOLID.
Principio de Responsabilidad Única (SRP)
Otro principio del conjunto SOLID. Establece que "solo existe una razón para cambiar una clase". Una clase solo debe abordar una tarea. Puede tener varios métodos, pero cada uno se utiliza únicamente para resolver la tarea general. Todos los métodos y propiedades deben servir solo a esto.

El valor de este principio radica en que debilita la conexión entre un componente de software y el código. Si se agrega más de una funcionalidad a una clase, se introduce una conexión entre dos funciones. Así, si se modifica una de ellas, hay una alta posibilidad de afectar la otra, que está relacionada con la primera. Esto significa un aumento en los ciclos de prueba para identificar todos los problemas de antemano.
Principio de Inversión de Dependencias (DIP)

En el ejemplo de código anterior, AppManager depende de EventLogWriter, que, a su vez, está estrechamente relacionado con AppManager. Si se necesita otra forma de mostrar una notificación, ya sea un push, SMS o email, hay que modificar la clase AppManager.
El problema puede resolverse utilizando DIP. Así, en lugar de AppManager, se solicita EventLogWriter, que será introducido mediante el marco de trabajo.
DIP permite reemplazar módulos individuales por otros sin problemas, cambiando el módulo de dependencia. Esto permite modificar un módulo sin afectar a los demás.
Composición en lugar de herencia
Las principales formas de reutilización de código son la herencia y la composición, cada una con sus ventajas y desventajas. Por lo general, se prefiere la segunda, ya que es más flexible.
La composición permite modificar el comportamiento de una clase en tiempo de ejecución ajustando sus propiedades. Al implementar interfaces se utiliza el polimorfismo, lo que proporciona una implementación más flexible.
Incluso "Effective Java" de Joshua Bloch aconseja preferir la composición en lugar de la herencia.
Principio de Sustitución de Barbara Liskov (LSP)
Otro principio del conjunto de herramientas SOLID. Establece que los subtipos deben ser reemplazables por su supertipo. Es decir, los métodos y funciones que trabajan con la superclase deben poder funcionar sin problemas también con sus subclases.
El LSP está relacionado tanto con el principio de responsabilidad única como con el principio de segregación de interfaces. Si una clase ofrece más funcionalidad que su subclase, esta última no podrá mantener algunas funciones, violando así este principio.
Aquí hay un fragmento de código que contradice el LSP.

El método area(Rectangle r) calcula el área de un Rectangle. El programa fallará al ejecutar Square, ya que Square no se considera un Rectangle aquí. Según el principio LSP, las funciones que utilizan referencias a clases base deben poder usar objetos de clases derivadas sin instrucciones adicionales.
Este principio, que es una definición específica de subtipo, fue propuesto por Barbara Liskov en 1987 en una conferencia durante una ponencia titulada 'Abstracción de datos e jerarquía', de ahí su nombre.
Principio de segregación de interfaces (ISP)
Otro principio SOLID. Según él, una interfaz que no se utiliza no debe ser implementada. Seguir este principio ayuda a que el sistema se mantenga flexible y adecuado para refactorizaciones al introducir cambios en la lógica de funcionamiento.
Esta situación ocurre con mayor frecuencia cuando una interfaz contiene varias funcionalidades y el cliente solo necesita una de ellas.
Dado que escribir una interfaz es una tarea complicada, después de completar su trabajo, cambiarla sin romper nada será un desafío.
La ventaja del principio ISP en Java es que primero se deben implementar todos los métodos, y solo después pueden ser utilizados por las clases. Por lo tanto, el principio permite reducir el número de métodos.

Programar para una interfaz, no para una implementación
Aquí queda claro por el nombre. La aplicación de este principio conduce a la creación de código flexible que podrá trabajar con cualquier nueva implementación de la interfaz.
Se debe utilizar el tipo de interfaz para variables, tipos de retorno o tipos de argumento de método. Un ejemplo es utilizar SuperClass en lugar de SubClass.
Es decir:
List numbers = getNumbers();
Y no:
ArrayList numbers = getNumbers();
Aquí hay una implementación práctica de lo que se menciona arriba.

El principio de delegación
Un ejemplo común son los métodos equals() y hashCode() en Java. Cuando se necesita comparar dos objetos, esta acción se delega a la clase correspondiente en lugar del cliente.
La ventaja del principio es la ausencia de duplicación de código y la relativa facilidad para modificar el comportamiento. También se aplica a la delegación de eventos.

Todos estos principios permiten escribir un código más flexible, bonito y fiable, con alta cohesión y bajo acoplamiento. Por supuesto, la teoría es buena, pero para que un desarrollador realmente comience a utilizar lo aprendido, se requiere práctica. El siguiente paso tras dominar los principios de la POO podría ser estudiar patrones de diseño para resolver problemas comunes en el desarrollo de software.
Skillbox recomienda:
- Curso práctico .
- Curso en línea aplicado .
- Curso práctico de dos años .
Fuente: habr.com
