Servicios de dominio como fachadas

8

Leí .NET Domain-Driven Design con C #: Problema - Diseño - Solución y noté que el autor creó un servicio de dominio para cada raíz agregada.

Sin embargo, los servicios de dominio solo eran fachadas al repositorio correspondiente. Por ejemplo, este es un ejemplo de código de la aplicación de su libro

public static class CompanyService
{
    private static ICompanyRepository repository;
    private static IUnitOfWork unitOfWork;

    static CompanyService()
    {
        CompanyService.unitOfWork = new UnitOfWork();
        CompanyService.repository = 
            RepositoryFactory.GetRepository<ICompanyRepository, 
            Company>(CompanyService.unitOfWork);
    }

    public static IList<Company> GetOwners()
    {
        return CompanyService.GetAllCompanies();
    }

    public static IList<Company> GetAllCompanies()
    {
        return CompanyService.repository.FindAll();
    }

    public static void SaveCompany(Company company)
    {
        CompanyService.repository[company.Key] = company;
        CompanyService.unitOfWork.Commit();
    }

    public static Company GetCompany(object companyKey)
    {
        return CompanyService.repository.FindBy(companyKey);
    }
}

Como puede ver, casi todas las llamadas a los servicios son contenedores para llamadas al repositorio. ¿Es este un buen patrón al crear servicios de dominio?

¿Deberíamos siempre envolver nuestros repositorios en servicios de dominio? ¿Hay un mejor enfoque?

Songo
fuente
¿Qué quieres decir con "mejor"?
Robert Harvey
La pregunta que me haría aquí es "¿qué valor proporciona el servicio de la empresa sobre el repositorio de la empresa?". Si la respuesta es ninguna, la clase es un intermediario: ¡elimínelo sin piedad!
MattDavey
@MattDavey bien en este ejemplo de código, puedo ver que los métodos del repositorio se tradujeron a llamadas de dominio. Por ejemplo, GetAllCompanies()envolturas repository.FindAll(). Sin embargo, ¿por qué no puedo crear un método de repositorio repository.GetAllCompanies()?
Songo
@Songo: Depende de si cualquier otro método en su capa de servicio también envuelve de manera similar una llamada al método de repositorio.
Robert Harvey

Respuestas:

7

Un repositorio está destinado a ser una abstracción para su almacén de datos y, en general, proporciona capacidades de recuperación de datos. Esta disposición le permite, por ejemplo, cambiar el almacén de datos para un almacén de datos diferente (por ejemplo, de Oracle a SQL Server, aunque en la práctica esto rara vez sucede), y su API de repositorio aún debería funcionar, si no expuso ninguno detalles específicos de implementación.

Una capa de servicio, por otro lado, es una API destinada a ser consumida por un usuario o agente externo, y proporciona servicios , no la recuperación de datos per se (aunque puede hacerlo). Una API de servicio puede recurrir a múltiples repositorios y realizar transformaciones en los datos antes de entregarlos al cliente. Puede envolver los datos en objetos personalizados o proporcionar capacidades de paginación. Puede hacer cosas en su capa de servicio más allá del simple almacenamiento y recuperación de datos.

Si no tiene la necesidad de proporcionar una capa adicional de abstracción más allá de lo que proporciona su repositorio, es posible que no necesite una capa de servicio.

Robert Harvey
fuente
1
+1 Una cosa me llamó la atención en el código que publiqué. El SaveCompanymétodo marca la unidad de trabajo. Si solo usara un repositorio, ¿la llamada para confirmar todos los cambios estaría en el repositorio?
Songo
Sí, sería ...
Robert Harvey
2

A medida que su aplicación crece, hay operaciones complejas que su capa de servicio puede ajustar y exponer. Es realmente una fachada sobre el modelo de dominio. Por ejemplo, en una aplicación de ventas, es posible que no le importe la línea de pedido como un objeto discreto dentro del modelo. Solo desea agregar artículos a un carrito, verificarlos e imprimir una factura para el usuario después de aplicar los descuentos.

Detrás de escena probablemente haya docenas de objetos involucrados en la interacción. El servicio puede proyectar una vista aplanada del modelo de objetos para que, a medida que el modelo de dominio cambie detrás de escena, el cliente no se vea afectado por esos cambios.

Michael Brown
fuente