Hoy vamos a ver el primer principio que conforma los principios SOLID. Este es, para mi, una de las reglas más importantes a seguir en la programación orientada a objetos, ya que al seguirlo podemos saber muy bien donde estamos no nos perdemos entre líneas y líneas de código. La imagen que ilustra esta entrada es un claro ejemplo de la responsabilidad única aplicada a la realidad.
La premisa básica de este principio es que una clase debe tener una única razón para cambiar. Supongamos que desarrollamos una clase coche. Esta clase tiene una serie de métodos, en los que encontramos los siguientes:
Esta claro que las acciones de arrancar o detener el coche son única responsabilidad para la clase coche. Sin embargo el método Conducir presenta otros problema. ¿Quién conduce el coche? ¿Por dónde lo conduce?. Ocurre lo mismo con el método lavar, ¿Quién lo lava? ¿Dónde lo lava?. Nos damos cuenta de que estas responsabilidades no pueden caer también sobre la clase coche, porque un cambio en los datos de éstos métodos o en la información que queremos obtener al consultarlos nos obligan a modificar esta clase.
Pongamos un ejemplo rápido y práctico de este principio. Siguiendo con el ejemplo anterior, crearemos nuestra clase coche:
class Car def initialize(color, name) @name = name @color = color @started = false puts "Tienes un coche nuevo llamado " + @name + " y de color " + @color end def start if self.started? puts "El coche ya está arrancado" else puts "Arrancando el coche" @started = true end end def stop if self.started? puts "Deteniendo el coche" @started = false else puts "El coche no está arrancado" end end def getName @name end def started? @started end end
Como vemos, nuestra clase coche es la que se encarga de arrancar el motor, o detenerlo. También tenemos unos atributos propios como el color del coche o el nombre del mismo. Supongamos que queremos conducir nuestro coche. Necesitaremos un conductor (aún queda tiempo para que los coches autónomos sean comunes entre nosotros). Siguiendo la lógica de responsabilidad única una forma de hacerlo sería crear una clase conductor que tuviera un coche (Por supuesto, la clase conductor que estamos creando podría ser hija de una clase persona):
class Driver def initialize(car, name) @name = name @car = car puts "Te llamas " + @name + " conduces un " + @car.getName end def drive if @car.started? puts "estamos conduciendo el coche" else puts "El coche no está arracancado, no puedes conducir" puts "¿Quieres arrancarlo? (Si/No)[Si]" STDOUT.flush driveCar = gets.chomp if ["SI","S",""].include?(driveCar.upcase) @car.start self.drive end end end end
Como vemos, en nuestra clase conductor, poseedora de un coche, la que se encarga de conducirlo, marcando los límites de responsabilidades en cada clase, de tal modo que si un día la forma de arrancar el coche y de conducirlo varían las responsabilidades recaen en cada una de sus partes.
Puedes encontrar más información sobre este principio en los siguientes enlaces, que también me han servido como fuente de información para esta entrada:
Principio de responsabilidad simple aplicado en Java
Principios SOLID en Ruby (inglés)
Principio de responsabilidad única por desarrolloweb
buenas prácticas, desarrollo, development, SOLID
[…] Single Responsibility – SOLID I […]