
Muy a menudo me encuentro con desarrolladores que no han escuchado acerca de los principios de SOLID (
hablamos de ellos en detalle aquí . - Transl.) O programación orientada a objetos (OOP), o escucharon, pero no los usan en la práctica. Este artículo describe los beneficios de los principios OOP que ayudan a un desarrollador en su trabajo diario. Algunos de ellos son bien conocidos, otros no son muy buenos, por lo que el artículo será útil tanto para principiantes como para programadores experimentados.
Le recordamos: para todos los lectores de "Habr": un descuento de 10.000 rublos al registrarse en cualquier curso de Skillbox con el código de promoción "Habr".
Skillbox recomienda: El curso de educación en línea para desarrolladores de Java .
SECO (no te repitas)
Un principio bastante simple, cuya esencia se desprende del título: "No repetir". Para el programador, esto significa la necesidad de evitar el código duplicado, así como la capacidad de utilizar la abstracción en el trabajo.
Si el código tiene dos secciones repetidas, se deben combinar en un método. Si un valor codificado se usa más de una vez, vale la pena convertirlo en una constante pública.
Esto es necesario para simplificar el código y facilitar su soporte, que es la tarea principal de OOP. Combinar el sindicato tampoco vale la pena, porque el mismo código no pasará la verificación con OrderId y SSN.
Encapsulación del cambio
Los productos de software de la mayoría de las empresas están en constante evolución. Por lo tanto, debe realizar cambios en el código, debe ser compatible. Puede simplificar su vida con la encapsulación. Esto permitirá pruebas y mantenimiento más eficientes de la base de código existente.
Aquí hay un ejemplo .
Si escribe en Java, entonces,
de forma predeterminada, asigne variables y métodos privados .
El principio de apertura / cercanía.
Este principio puede recordarse fácilmente leyendo la siguiente declaración: "Las entidades de software (clases, módulos, funciones, etc.) deben estar abiertas para la expansión, pero cerradas para el cambio". En la práctica, esto significa que pueden permitirle cambiar su comportamiento sin cambiar el código fuente.
El principio es importante cuando los cambios en el código fuente requieren revisión, pruebas unitarias y otros procedimientos. El código que obedece el principio de apertura / cercanía no cambia durante la expansión, por lo que hay muchos menos problemas con él.
Aquí hay un ejemplo de código que viola este principio.

Si necesita cambiar algo en él, tomará mucho tiempo, ya que tendrá que cambiar todas las secciones del código que tengan una conexión con el fragmento deseado.
Por cierto, la apertura-cierre es uno de los principios de SOLID.
Principio de responsabilidad única (SRP)
Otro principio de la suite SOLID. Afirma que "solo hay una razón que conduce a un cambio de clase". Una clase resuelve solo un problema. Puede tener varios métodos, pero cada uno de ellos se usa solo para resolver un problema común. Todos los métodos y propiedades deberían servir solo para esto.

El valor de este principio es que debilita la conexión entre el componente de software individual y el código. Si agrega más de una funcionalidad a una clase, esto introduce una conexión entre las dos funciones. Por lo tanto, si cambia uno de ellos, existe una gran posibilidad de estropear el segundo, asociado con el primero. Y esto significa un aumento en los ciclos de prueba para identificar todos los problemas de antemano.
Principio de inversión de dependencia (DIP)

Lo anterior es un código de ejemplo donde el AppManager depende de un EventLogWriter, que a su vez está estrechamente relacionado con el AppManager. Si necesita otra forma de mostrar una notificación, ya sea push, SMS o correo electrónico, debe cambiar la clase AppManager.
El problema puede resolverse usando DIP. Entonces, en lugar de AppManager, solicitamos un EventLogWriter, que se introducirá utilizando el marco.
DIP le permite reemplazar fácilmente módulos individuales con otros, cambiando el módulo de dependencia. Esto hace posible cambiar un módulo sin afectar el resto.
Composición en lugar de herencia

Hay dos formas principales de reutilizar el código: esto es herencia y composición, y cada una tiene sus propias ventajas y desventajas. El segundo generalmente se prefiere porque es más flexible.
La composición le permite cambiar el comportamiento de una clase en tiempo de ejecución estableciendo sus propiedades. Al implementar interfaces, se utiliza el polimorfismo, lo que proporciona una implementación más flexible.
Incluso "Java eficaz" de Joshua Bloch aconseja dar preferencia a la composición en lugar de la herencia.
Principio de sustitución de Barbara Lisk (LSP)
Otro principio del kit de herramientas SOLID. Establece que los subtipos deben ser reemplazables para un supertipo. Es decir, los métodos y funciones que funcionan con una superclase deberían poder trabajar con sus subclases sin problemas.
El LSP está conectado tanto con el principio de responsabilidad única como con el principio de división de responsabilidad. Si una clase proporciona más funcionalidad que una subclase, entonces esta última no admitirá algunas funciones, violando este principio.
Aquí hay un fragmento de código que contradice el LSP.

El método del área (Rectángulo r) calcula el área del Rectángulo. El programa se bloqueará después de ejecutar Square, ya que Square no es un Rectángulo aquí. De acuerdo con el principio LSP, las funciones que usan referencias a clases base deberían poder usar objetos de clases derivadas sin instrucciones adicionales.
Este principio, que es una definición específica de un subtipo, fue propuesto por Barbara Liskov en 1987 en una conferencia en el informe principal titulado "Abstracción de datos y jerarquía", de ahí su nombre.
Principio de separación de interfaz (ISP)
Otro principio SÓLIDO. Según él, una interfaz que no se utiliza no debe implementarse. Seguir este principio ayuda a que el sistema permanezca flexible y adecuado para la refactorización al realizar cambios en la lógica de trabajo.
Con mayor frecuencia, esta situación ocurre cuando la interfaz contiene varias funcionalidades a la vez, y el cliente solo necesita una de ellas.
Dado que escribir una interfaz es una tarea difícil, después de completar el trabajo, cambiarla sin romper nada será un problema.
La ventaja del principio ISP en Java es que todos los métodos deben implementarse primero, y solo entonces pueden ser utilizados por las clases. Por lo tanto, el principio permite reducir el número de métodos.

Programación para una interfaz, no una implementación
Todo aquí está claro por el nombre. La aplicación de este principio conduce a la creación de código flexible que puede funcionar con cualquier implementación de interfaz nueva.
Utilice el tipo de interfaz para variables, tipos de retorno o el tipo del argumento del método. Un ejemplo es el uso de SuperClass, no SubClass.
Eso es:
Lista de números = getNumbers ();Y no:
ArrayList números = getNumbers ();Aquí hay una implementación práctica de lo que se dijo anteriormente.

Principio de delegación
Un ejemplo común son los métodos equals () y hashCode () en Java. Cuando se requiere comparar dos objetos, esta acción se delega a la clase correspondiente en lugar del cliente.
Una ventaja del principio es la ausencia de duplicación de código y un cambio de comportamiento relativamente simple. También es aplicable a la delegación de eventos.

Todos estos principios permiten escribir códigos más flexibles, hermosos y confiables con alta conectividad y bajo engranaje. Por supuesto, la teoría es buena, pero para que el desarrollador realmente comience a usar el conocimiento adquirido, se necesita práctica. El siguiente paso después de dominar los principios de OOP puede ser el estudio de patrones de diseño para resolver problemas comunes de desarrollo de software.
Skillbox recomienda: