-
-
Save eamodeorubio/857561 to your computer and use it in GitHub Desktop.
public class AuditorTransferenciasMonetarias { | |
/* Ahora la clase implementa lógica de negocio "pura" | |
* y es independiente de la plataforma (a.k.a. framework) | |
*/ | |
private DirectorioEmpleados directorioEmpleados; | |
private SistemaMensajeriaCorporativa mensajero; | |
private PlantillasCorporativas almacenDePlantillas; | |
/* No se muestra todo el código */ | |
public void transferenciaRealizada(Transferencia transferencia) { | |
if(transferencia.esImportante()) { | |
this.mensajero | |
.enviar( | |
new Mensaje() | |
.a(interesadosEnTransferenciasImportantes() | |
.conContenido(this.componerMensajeAviso(transferencia)) | |
); | |
} | |
} | |
private Documento componerMensajeAviso(Transferencia transferencia) { | |
return this.almacenDePlantillas.usandoPlantilla("avisos/transferencia-importante").crearDocumentoCon(transferencia); | |
} | |
private List<Empleado> interesadosEnTransferenciasImportantes() { | |
return this.directorioEmpleados.empleadosConRol(Empleado.INTERESADOS_TRANSFERENCIAS_IMPORTANTES); | |
} | |
} |
La decisión de si una transferencia es importante o no podemos delegarla en la propia transferencia. A su vez la transferencia podría delegarla a una regla de negocio externa o un helper, si vemos que se va a cambiar dicha definición mediante en runtime mediante un backoffice o algo así.
Ahora delegamos la responsabilidad de a quien debemos notificar en el directorio de empleados. La asociación de que empleados están interesados se hace mediante un rol, y podríamos llegar a cambiarla en runtime mediante un backoffice.
Ahora usamos un sistema de mensajería abstracto. Puede tener varias implementaciones, SMS, correo, impresora, web, etc. De hecho podríamos tener una implementación "composite" que redirigiera la notificación a varios sistemas de mensajería.
Para aislar a la clase de cambios en el framework, usamos tres interfaces de negocio, PlantillasCorporativas, Plantilla y Documento.
Ahora si cambiamos de framework esta clase no hay que tocarla. Además, en vez de usar String, usamos Documento, que podría (si fuera necesario) saber como serializarse en String, en array de bytes, en HTML, en XML o en JSON, según le interese a la implementación concreta de SistemaMensajeriaCorporativa que usemos.
Una clase cuya responsabilidad es la siguiente:
"Cuando se produce una transferencia de dinero importante
Entonces se produce una notificación de este hecho
Para que se pueda autorizar la transferencia y se evite el fraude"
Sin embargo esta implementación viola el SRP. Existen varias razones por la que puede cambiar, algunas de ellas son:
a) La forma de notificación cambia. Tal vez deja de ser por e-mail y pasa a ser por SMS
b) A quien hay que avisar cambia. En vez de a un auditor, pueden ser varios. O tal vez a los auditores y al director de la sucursal.
c) La definición de transferencia importante cambia
d) En un mes el framework Zprin puede quedar deprecated y fuera de soporte y debemos cambiar al nuevo framework Xpringio
La única razón válida por la que debería cambiar la implementación es que la historia de usuario cambie. Por ejemplo, que además de notificar la transferencia, se avise al ordenante de que su transferencia está siendo evaluada. O tal vez, que ya no se notifique el cambio sino que se aplique una regla automática para saber si se autoriza o no. O quizás que hay que notificar todas las transferencias, no sólo las importantes.