oop - tutorial - Desacoplamiento del modelo de servicio: ¿qué sucede si mi modelo necesita un servicio?
the django project (3)
La capa de Servicio se supone que está encima de la capa del Modelo. Como tal, los modelos no deben llamar a servicios.
Sin embargo, estoy enfrentando una situación en la que necesito, por ejemplo:
interface Component {
getResult();
}
class Number implements Component {
private value;
public getResult() {
return value;
}
}
class Addition implements Component {
private component1;
private component2;
public getResult() {
return component1->getResult() + component2->getResult();
}
}
class ConstantFromExternalSource implements Component {
private identifier;
public getResult() {
// call a service for fetching constant identified by identifier
}
}
(pseudo-código)
Aquí, mi modelo necesita acceder a una fuente de datos externa a través de un Servicio (servicio web o no).
¿Cómo se supone que debo hacer en esta situación? ¿Está bien llamar a un servicio en el modelo?
Si sugiere alejar el método "getResult" del modelo y ponerlo en el "ComponentService", estaría en desacuerdo porque luego perdería todas las ventajas de OOP (y aquí mi modelo crea un árbol que necesita resolverse recursivamente) , entonces OOP es la mejor solución).
Quisiera que la fuente externa devolviera directamente la constante como Componente. No asociaría la clase ConstantFromExtenralSource a un servicio, ni siquiera como interfaz, porque la clase (al menos en este formulario) no hace más que llamar al servicio.
Sin embargo, si la fuente externa devuelve algunos datos que deben completarse en la clase ConstrantFromExternalSource, simplemente insertaría los datos en el objeto a través del constructor.
En pocas palabras, si el modelo es solo una herramienta para obtener datos de una fuente externa, simplemente use un Repositorio para obtener los datos de manera activa y para devolver un modelo si la fuente externa no devolverá directamente el objeto que necesita.
¿Está bien llamar a un servicio en el modelo?
Depende de qué tipo de servicio. En lo que respecta a DDD,
El dominio definitivamente no debe conocer los servicios subyacentes de la capa de aplicaciones que consumen el dominio.
Los servicios de capa de dominio no son un gran problema ya que son parte de la misma capa.
Por el contrario, los servicios de capa de infraestructura deben ser inyectados en los objetos de su dominio y sus interfaces deben declararse en la capa de dominio si desea un acoplamiento flexible entre el dominio y la infraestructura (lo mismo que con las interfaces / implementaciones del repositorio). Sergey tiene una buena implementación de esto.
Puedes lograr esto de varias maneras. En primer lugar, puede extraer la dependencia de su modelo en una interfaz separada como:
interface CustomService {
getResult();
}
class ExternalService implments CustomService
{
getResult() { // access web service }
}
Y luego inyecte esa dependencia en el modelo:
class ConstantFromExternalSource implements Component {
private identifier;
private CustomService service;
ConstantFromExternalSource(CustomService service)
{
this.service = service;
}
public getResult() {
// call a service for fetching constant identified by identifier
return service.getResult();
}
}
Otra forma de lograr esto es utilizar el Patrón de diseño del observador y notificar abstracciones de mayor nivel de las que necesita algo de ellos.
En ambos sentidos, puede desacoplar su modelo de la implementación concreta de la capa de servicio.