- SRP - Single Responsibility Principle (Principio de Responsabilidad Única)
- OCP - Open/Closed Principle (Principio Abierto / Cerrado)
- LSP - Liskov Substitution Principle (Principio de Sustitución de Liskov)
- DIP - Dependency Inversion Principle (Principio de Inversión de Dependencias)
- ISP - Interface Segregation Principle (Principio de Segregación de Interfaces)
http://en.wikipedia.org/wiki
http://en.wikipedia.org/wiki
http://en.wikipedia.org/wiki
1. SRP - Single Responsibility Principle (Principio de Responsabilidad Única)
- Cambio mi motor de base de datos, de XXSql paso a NNSql.
Debo cambiar mi clase Cliente. - Cambio la forma de crear la salida HTML
Debo cambiar mi clase Cliente. - Agrego un reporte o modifico uno existente
Debo cambiar mi clase Cliente. - Cambio la política para calcular la presencia en el mercado
Debo cambiar mi clase Cliente.
Posiblemente esa falta de cohesión nos lleve a otro problema, para mi es una regla que se cumple con rigor matemático,acoplamiento.
Que sucede entonces con aquellos metodos que ya no existen en Cliente?, bueno será nuestro trabajo buscar quienes tienen la responsabilidad de resolver esas cuestiones. Lo importante aquí es que Cliente atienda sus responsabilidades directas, aquellas en las que es experto.2. OCP - Open/Closed Principle (Principio Abierto / Cerrado)
Enunciado formal: "Entidades de Software (clases, módulos, funciones, etc) deberían ser abiertas para la extensión y cerradas para la modificación"
Traducido sería: el diseño que incluye nuestra clase, una vez concluida su implementación, no debería cambiar, porque si lo hace, podría generar un efecto en cadena sobre todas las clases que la usan. Pero se puede extender al permitir seguir agregando clases clientes con solo implementar la interfaz y sin tener que cambiar el código de implementación de la clase Impresora.
Abierto / cerrado
Una posible solución para lo relacionado con la persistencia podría ser la siguiente:

Propongamos un cambio en el requerimiento y veamos.
Problema planteado, que nos dice el principio Abierto/Cerrado?
La aplicación del principio a nuestro problema podría ser agregar una interface o una clase abstracta que sea bien conocida por Ventas, ClienteDB debería implementar la interface o heredar de la clase abstracta.
En el diagrama se puede apreciar la implementación para una cuestión más terrenal, mockobjects y test unitarios.
3. LSP - Liskov Substitution Principle (Principio de Sustitución de Liskov)
Enunciado formal: "Subtipos deben ser sustituibles por sus clases bases"
Vamos a aprovechar la capacidad de extensión que nos brindan los lenguajes OO, estamos frente a nuestra clase Cliente, con algunos cambios ya que los requerimientos del sistema han cambiado con el transcurso del tiempo y ahora un nuevo requerimiento nos exige considerar Clientes presenciales y Clientes virtuales.

Posiblemente el programador haga algo así:
if( typeof... )
//Tratamiento para ClienteVirtual
else
//Tratamiento para Cliente
El problema entonces es que CentroAutorización ya no puede tratar a ClienteVirtual como Cliente, debe conocer las características de la sub clase porque esta altera el comportamiento de la clase Cliente. ( Comportamiento, no implementación de comportamiento).
La solución en este caso es revisar eol diseño, posiblemente ClienteVirtual no este en la línea de herencia de Cliente, tal como pensamos en principio.
No atender estas cuestiones hace que nuestro diseño sea críptico, que los programadores no puedan confiar en la extensión de las clases y deban conocer el comportamiento de de cada una de ellas.
Bueno, para evitar esto debemos respetar el principio de sustitución. El mismo expresa:
La aplicación de este principio garantiza de alguna manera el éxito en la aplicación de los principios de Responsabilidad única y Abierto / cerrado.
4. DIP - Dependency Inversion Principle (Principio de Inversión de Dependencias)
Enunciado formal: "los clientes tienden a ser propietarios de las interfaces y aquellos que ofrecen los servicios las implementan"
Inversión de dependencia
Modelamos, sea en papel, en UML, en nuestra mente, como sea, lo hacemos. Creamos artefactos, clases por lo general, y relacionamos esos artefactos unos con otros.
Cuando hacemos esto, relacionar artefactos, establecemos dependencia entre ellos. Un artefacto deberá conocer a otro. El artefacto B requiere un artefacto del tipo C y otro del tipo D.
Vamos a implementar un pequeño modulo de registro de eventos para tener un ejemplo concreto de como nos afectan las dependencias en un modelo.
Nuestro módulo de registro incluirá unas pocas clases, veamos un diagrama:
Lo primero que se aprecia es la asignación correcta de responsabilidades, hemos asimilados los principios OOD vistos hasta ahora. :)- La clase LogHelper depende de Message
- La clase LogHelper depende de TextFile
El segundo caso es más complejo, mi definición habla de algún dispositivo de salida, mi primer dispositivo es TextFile, cambiar o agregar algún otro dispositivo de salida implicará cambios profundos en LogHelper.
Este último problema va más allá del acoplamiento, nuestro modelo esta acoplado y además es rígido.
El principio de Inversión de dependencia nos ayuda a eliminar o acotar este tipo de problemas, que nos dice el principio?
Ambos deben depender de abstracciones.
LogHelper ya no depende de TextFile, lo hace de OutPutProvider, la notación itálica nos indica que es una clase abstracta.Quiero resaltar un concepto, en la definición del principio hablamos de Módulo de Nivel Superior.
Estos son menos propensos al cambio, son los que expresan nuestro negocio, representan el dominio del problema, su mención no es casual.
En cada Nivel atenderemos un Negocio determinado, aplicar Inversión de dependencia implica conocer los límites, el borde de cada nivel.
5. ISP - Interface Segregation Principle (Principio de Segregación de Interfaces)
Enunciado formal: "Clientes no deberían depender de métodos que no utilizan"
Existen situaciones en las que una misma clase será consumida por distintos clientes, agentes que solo necesitan conocer un conjunto acotado de responsabilidades de esa clase. Sin embargo esas clases siguen representando un concepto único en el modelo.
Es una situación ambigua, la clase sigue siendo cohesiva y quienes la consumen manejan un concepto acotado de la misma en el dominio.
Supongamos una clase Cliente, nuestra clase es consumida por agentes que están interesados en distintos aspectos:

- Despacho
Solo necesita conocer el Domicilio - BuzonEletronico
Solo necesita cono cer la dirección electrónica.
Tenemos ahora un modelo mas elegante, mas cohesivo, poco acoplado.la "Ley de Deméter": Habla sólo con tus amigos inmediatos. Traduciendo el enunciado formal
Un método M de un objeto O solo debería invocar métodos:Así se consigue que la dependencia de la estructura entre las clases no vaya arrastrando más de un nivel. Eso si, provoca algún nivel de indirección más.
- suyos
- de sus parámetros
- objetos que cree o instancie
- objetos miembros de la clase (atributos)
el principio del “punto de control individual”.
el cambio puede realizarse en un único punto del código. Nos limitamos a modificar el procedimiento:
public class StandardOutReporter {
public static void report (String msg) {
System.out.println (msg + “a” + nueva Fecha());
}
}
Matthias Felleisen llama a esto el principio del “punto de control individual”. En este caso, el mecanismo nos resulta familiar: ya que se denominó abstracción por parametrización, porque cada llamada al procedimiento:
StandardOutReporter.report (“Comenzando descarga”);
es una instanciación de la descripción genérica, con el parámetro msg ligado a un valor especial.

