Actividad foro

Noticia

Cuando uno busca un cambio de trabajo se tiene que preparar un poco para las entrevistas técnicas, ya que muchas veces aunque seamos buenos ingenieros, es fácil olvidar uno de los tantos recursos que tenemos a nuestra disposición, ya bien sean patrones de diseño o principios aplicables a la programación orientada a objetos.

Una de estas cosas son los principios SOLID, en los que cada letra es cada uno de los siguientes principios:
S = Single Responsibility Principle (Principio de Responsabilidad Única)
O = Open Closed Principle (Principio Abierto/Cerrado)
L = Liskov Substitution Principle (Principio de Substitución de Liskov)
I = Interface Segregation Principle (Principio de Segregación de Interfaces)
D = Dependency Inversion Principle (Principio de Inversión de Dependencias)

Con el nombre de cada principio podemos intuir por donde van los tiros, pero no es suficiente, creo que es necesario una explicación rápida y una forma de comprobar que lo estamos aplicando correctamente.


  • Single Responsibility Principle (Principio de Responsabilidad Única)

  • There should never be more than one reason for a class to change.

    Este principio nos dice que cada clase sólo debería hacer/encargarse de una cosa o, en otras palabras, de tener una única responsabilidad.

    Regla para saber si estamos aplicando bien este principio: ¿Hace nuestra clase muchas cosas?
    Ejemplo muy básico y muy rápido del típico error que todos hemos cometido: tenemos la clase A y esa clase A queremos que se imprima por consola y que se guarde en un fichero, pero en un futuro lo mismo queremos que se imprima en un log y se guarde en una base de datos.
    En vez de tener una sola clase A deberíamos tener en un principio tres clases, la clase A, la clase Consola y la clase Fichero.
    Y alterarlas o crear nuevas clases en un futuro en base a nuestras necesidades.

  • Open Closed Principle (Principio Abierto/Cerrado)

  • Software entities should be open for extension, but closed for modification.

    Este principio nos dice que una clase debería estar abierta a extender su comportamiento añadiendo nueva funcionalidad pero sin necesidad de modificar el código existente.

    Regla para saber si estamos aplicando bien este principio: ¿Puedo añadir nuevas funcionalidades usando nuevas clases y/o métodos sin modificar el código existente?
    Usando el ejemplo anterior, tendríamos una clase abstracta Guardar que tendría tantos hijos como fueran necesarios, en nuestro caso en un principio Fichero y más adelante Database.
    Esto implica el uso de herencia y polimorfismo.

  • Liskov Substitution Principle (Principio de Substitución de Liskov)

  • Functions that use pointers or references to base classes must be able to use objects of derived classes without knowing it.

    Este principio nos dice que si en alguna parte de nuestro código estamos usando una clase y esta clase es extendida, tenemos que poder utilizar cualquiera de las clases hijas y que el programa siga siendo válido.

    Regla para saber si estamos aplicando bien este principio: ¿Tienen sentido todos los métodos de mi clase base en las clases derivadas?
    Ejemplo rápido y sencillo: Tenemos la clase Animal y dentro de animal implementamos andar y saltar. Ahora creamos la clase Elefante que hereda de Animal, pero un elefante no puede saltar... Así que ya la tendríamos liada salvo que pensemos en alguna forma de diferenciar entre animales que pueden saltar y los que no.
    Una forma sencilla sería hacer la clase Animal que no pudiera saltar, una intermedia de animales que sí que puedan saltar, por ejemplo, Saltarines y finalmente Elefante heredaría de Animal sin ningún problema.

  • Interface Segregation Principle (Principio de Segregación de Interfaces)

  • Clients should not be forced to depend upon interfaces that they do not use.

    Este principio nos dice que ninguna clase debería depender de métodos que no usa y que por tanto cuando creemos interfaces, es importante estar seguros de que todas las clases que implementen esas interfaces vayan a necesitar y ser capaces de agregar comportamientos a todos los métodos. En caso contrario, es mejor tener varias interfaces más pequeñas.

    Regla para saber si estamos aplicando bien este principio: ¿Al implementar una interfaz te ves obligado a dejar sin implementar (o lanzar una excepción) uno o varios métodos porque no tienen sentido?
    Ejemplo rápido y sencillo: Tenemos la clase B que implementa la interfaz A que tiene los campos a, b y c. Ahora aparece la clase C que implementa también la interfaz A pero que necesita un nuevo campo d. La clase B no tiene ese campo ni tiene sentido, por lo que tener, por ejemplo, un setter o un getter en la interfaz hace que la clase B quede rara.

  • Dependency Inversion Principle (Principio de Inversión de Dependencias)

  • Depend upon abstractions, [not] concretions.

    Este principio nos dice dos cosas fundamentales:
    A. Las clases de alto nivel no deberían depender de las clases de bajo nivel. Ambas deberían depender de las abstracciones.
    B. Las abstracciones no deberían depender de los detalles. Los detalles deberían depender de las abstracciones.

    Regla para saber si estamos aplicando bien este principio: ¿Puedes probar (mediante test) una clase con facilidad o te cuesta porque depende del código de otra clase?

Noticias