Acerca de la programación orientada a objetos

Se cree que la programación orientada a objetos se basa en tres pilares que brindan al programador ventajas sobre el enfoque procesal. Son encapsulación, herencia y polimorfismo.La herencia le permite deshacerse significativamente de la duplicación de código cuando utiliza el enfoque orientado a objetos. Pero al usarlo, siempre debe recordar uno de los principios de SOLID, llamado Sustitución de Liskov, que, a menos que entre en detalles, establece que la herencia debe usarse solo como una implementación de la relación "es". Es decir, la clase del descendiente debe "ser" una subespecie del padre. Por ejemplo, puede tener la clase Bird y sus subclases Sparrow (gorrión) y Raven (cuervo), que, por ejemplo, heredan (y pueden extender o modificar) el método fly. Sin embargo, si crea un descendiente de Bird llamado Penguin (pingüino) y su método de vuelo, por ejemplo, arroja una excepción (porque los pingüinos no vuelan), esto violará el principio de sustitución de Liskov. Hablando de herencia,También vale la pena mencionar un principio importante al que se adhiere la Banda de los Cuatro (Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides) en su libro Design Patterns: Elements of Reusable Object-Oriented Software (1994), que establece que debe intentar usar composición (cuando un objeto "contiene" otro objeto) en lugar de heredar tanto como sea posible. En realidad, muchos de los patrones de diseño inventados por la "Banda de los Cuatro" se basan precisamente en este principio.En realidad, muchos de los patrones de diseño inventados por la "Banda de los Cuatro" se basan precisamente en este principio.En realidad, muchos de los patrones de diseño inventados por la "Banda de los Cuatro" se basan precisamente en este principio.

En general, en la práctica, la herencia se usa por no decir tan a menudo, incluso a pesar de que en la mayoría de los casos los buenos programadores la reemplazan con una composición. Más a menudo hay múltiples implementaciones de una interfaz, que se especifican como dependencias en las clases de clientes. Lo que a su vez le permite usar el segundo pilar de la POO: el polimorfismo. Lo que le permite pasar diferentes implementaciones de dependencia al código del cliente. Debido al hecho de que las dependencias transmitidas tienen la misma interfaz, al cliente (dependiendo de la interfaz) no le importa qué objeto le llegó y esto le permite al programador cambiar, durante la ejecución del programa, de qué manera (qué implementación de la interfaz) se resolverá la tarea final. Hablando de OOP, uno no puede dejar de mencionar la encapsulación. Este es un elemento esencial de OOP,que proporciona la capacidad de crear abstracciones para ocultar detalles de implementación de bajo nivel al tiempo que reduce la complejidad del desarrollo. Los detalles de implementación están ocultos por los modificadores de acceso a métodos como privado y protegido. Al crear clases, debe crearlas para que sus interfaces (métodos públicos accesibles) proporcionen una abstracción coherente,de lo contrario, ya no es OOP (!) . Por ejemplo, supongamos que estamos desarrollando un programa que controla el sistema de enfriamiento de un reactor nuclear. Entonces la abstracción acordada de la interfaz puede verse de la siguiente manera.

CoolingSystem::getTemperature()
CoolingSystem::SetCirculationRate($rate)
CoolingSystem::OpenValve($valveNumber)
CoolingSystem::CloseValve($valveNumber)

Gracias a una interfaz expresiva corta que forma una abstracción coherente, podemos trabajar con el sistema de enfriamiento del reactor sin tener la más mínima idea sobre los detalles de implementación de bajo nivel que son característicos de la tecnología seleccionada. El uso de abstracciones puede reducir significativamente la complejidad del sistema desarrollado. Y la lucha contra la complejidad es el principal imperativo técnico del desarrollo. Aquí hay algunos ejemplos más de abstracciones consistentes:

Sistema de control de velocidad:

  • Velocidad fijada
  • Obtener configuraciones actuales
  • Restaurar el valor de velocidad anterior
  • Deshabilitar sistema

Molinillo de café:

  • Habilitar
  • Apagar
  • Velocidad fijada
  • Comience a moler café
  • Deja de moler café

Depósito de combustible:

  • Llenar el tanque de combustible
  • Drene el combustible
  • Obtenga la capacidad del tanque de combustible
  • Obtener el estado del tanque de combustible

Lámpara:

  • Habilitar
  • Apagar

Al diseñar la interfaz de un objeto, declare públicos solo aquellos métodos que el cliente necesita para administrar, ocultando todo lo demás. Como resultado, debería obtener cuadros negros, cuyo dispositivo puede olvidar después de que se haya agregado el código de clase. Este enfoque puede reducir significativamente la complejidad del sistema desarrollado.

All Articles