Convenciones de nomenclatura DAL, BAL y UI Layer [cerrado]

35

Estoy desarrollando una aplicación web típica con las siguientes capas

  1. Capa de IU (MVC)
  2. Capa de lógica empresarial (BAL)
  3. Capa de acceso a datos (DAL)

Cada capa tiene su propio objeto DTO, incluidos BAL y DAL. Mis preguntas sobre esto son las siguientes

  1. El DTO devuelto por el DAL simplemente se convierte en el DTO correspondiente en el BAL y se envía a la capa UI. Ambos atributos y la estructura de los objetos DTO son iguales en algunos casos. En tales escenarios, es mejor simplemente devolver el DTO en el DAL a la capa de la interfaz de usuario sin incluir un objeto intermedio.

  2. ¿Cuál es la mejor manera de nombrar estos objetos DTO y otros objetos en cada capa? ¿Debo usar algún prefijo como DTOName, ServiceName? La razón por la que solicito usar un prefijo es porque si no las clases en mi Solución chocan con otras clases en el Marco y con un prefijo, ¿es más fácil para mí entender dónde pertenece cada clase?

usuario3631883
fuente
1
¿Estás usando el espacio de nombres?
JeffO

Respuestas:

48

Prefacio

Esperemos que esto sea obvio, pero ... en los espacios de nombres sugeridos a continuación, reemplazaría MyCompanyy MyProjectcon los nombres reales de su empresa y proyecto.

DTO

Recomendaría usar las mismas clases DTO en todas las capas. Menos puntos de mantenimiento de esa manera. Por lo general, los pongo bajo un MyCompany.MyProject.Modelsespacio de nombres, en su propio proyecto VS del mismo nombre. Y generalmente los llamo simplemente por la entidad del mundo real que representan. (Idealmente, las tablas de la base de datos también usan los mismos nombres, pero a veces tiene sentido configurar el esquema de manera un poco diferente allí).

Ejemplos: Person, Address,Product

Dependencias: ninguna (que no sea .NET estándar o bibliotecas auxiliares)

DAL

Mi preferencia personal aquí es usar un conjunto uno por uno de clases DAL que coincidan con las clases DTO, pero en un MyCompany.MyProject.DataAccessespacio de nombres / proyecto. Los nombres de clase aquí terminan con un Enginesufijo para evitar conflictos. (Si no le gusta ese término, entonces un DataAccesssufijo también funcionaría bien. Simplemente sea coherente con lo que elija). Cada clase proporciona opciones CRUD simples que afectan a la base de datos, utilizando las clases DTO para la mayoría de los parámetros de entrada y tipos de retorno (dentro un genérico Listcuando hay más de uno, por ejemplo, el retorno de un Find()método).

Ejemplos: PersonEngine, AddressEngine,ProductEngine

Dependencias: MyCompany.MyProject.Models

BAL / BLL

También un mapeo uno por uno aquí, pero en un MyCompany.MyProject.Logicespacio de nombres / proyecto, y con las clases obteniendo un Logicsufijo. ¡Esta debería ser la única capa que llama al DAL! Las clases aquí a menudo son solo un simple paso al DAL, pero si es necesario implementar reglas de negocios, este es el lugar para hacerlo.

Ejemplos: PersonLogic, AddressLogic,ProductLogic

Dependencias: MyCompany.MyProject.Models,MyCompany.MyProject.DataAccess

API

Si hay una capa API de servicios web, utilizo el mismo enfoque uno por uno, pero en un MyCompany.MyProject.WebApiespacio de nombres / proyecto, con Servicesel sufijo de clase. (A menos que esté utilizando la API web ASP.NET, en cuyo caso, por supuesto, usaría el Controllersufijo).

Ejemplos: PersonServices, AddressServices,ProductServices

Dependencias: MyCompany.MyProject.Models, MyCompany.MyProject.Logic(nunca derivación esto llamando al DAL directamente!)

Una observación sobre la lógica empresarial

Parece ser cada vez más común que las personas omitan el BAL / BLL y, en su lugar, implementen la lógica de negocios en una o más de las otras capas, donde sea que tenga más sentido. Si hace esto, asegúrese de que (1) todo el código de la aplicación atraviesa la capa o capas con la lógica de negocios, y (2) es obvio y / o está bien documentado dónde se ha implementado cada regla comercial en particular. En caso de duda, no intente esto en casa.

Una nota final sobre arquitectura de nivel empresarial

Si se encuentra en una empresa grande u otra situación en la que las mismas tablas de bases de datos se comparten en varias aplicaciones, le recomendaría que deje la MyProjectparte de los espacios de nombres / proyectos anteriores. De esa manera, esas capas pueden ser compartidas por múltiples aplicaciones front-end (y también por utilidades detrás de escena como los Servicios de Windows). ¡Pero solo haga esto si tiene una comunicación fuerte entre equipos y pruebas exhaustivas de regresión automatizada en su lugar! De lo contrario, es probable que los cambios de un equipo en un componente central compartido rompan la aplicación de otro equipo.

Troy Gizzi
fuente
2
Sé que esta es una publicación antigua pero en un espíritu de reconocimiento. Solo quería decir que encontré que esto es útil y conciso en un tema que deja mucho por debatir. ¡Gracias por compartir esto!
James Shaw
7

Usualmente construyo aplicaciones como

ProjectName.Core            // "framework"/common stuff
|- Extenders
|- Gravatar.cs

ProjectName.DataProvider    // database provider layer
|- Migrations
|- ApplicationDbContext.cs  // entity framework

ProjectName.Domain          // database objects
|- Post.cs
|- Tag.cs

ProjectName.Services        // validations, database stuff
|- PostService.cs

Es algo similar a Sharp-Lite .

Sobre los prefijos, los odio. Las pautas de codificación interna de Microsoft también los odian. También hay una herramienta llamada StyleCop que también se queja de los prefijos.

BrunoLM
fuente
Gracias por el puntero, pero mi problema principal es que, sin usar los prefijos, a veces es difícil determinar qué clases es de dónde, por ejemplo, tengo una clase llamada desde Connection y esto causa varias confusiones, mientras que si tuviera usado un prefijo las cosas habrían sido mucho más simples.
user3631883