Convenzioni di denominazione DAL, BAL e UI Layer [chiuso]


35

Sto sviluppando una tipica applicazione Web con i seguenti livelli

  1. UI Layer (MVC)
  2. Livello logico aziendale (BAL)
  3. Data Access Layer (DAL)

Ogni livello ha il proprio oggetto DTO, inclusi BAL e DAL. Le mie domande al riguardo sono le seguenti

  1. Il DTO restituito dal DAL viene semplicemente convertito nel DTO corrispondente nel BAL e inviato allo strato dell'interfaccia utente. Sia gli attributi che la struttura degli oggetti DTO sono gli stessi in alcuni casi. In tali scenari è meglio semplicemente restituire il DTO nel DAL allo strato dell'interfaccia utente senza includere un oggetto intermedio.

  2. Qual è il modo migliore per nominare questi oggetti DTO e altri oggetti in ogni livello. Dovrei usare un prefisso come DTOName, ServiceName? Il motivo per cui sto chiedendo di usare un prefisso è perché se non le classi nella mia soluzione si scontrano con altre classi nel Framework e con un prefisso, è più facile per me capire dove appartiene ogni classe?



1
Stai usando lo spazio dei nomi?
JeffO,

Risposte:


48

Prefazione

Spero che questo sia ovvio, ma ... negli spazi dei nomi suggeriti di seguito, sostituiresti MyCompanye MyProjectcon i nomi reali della tua azienda e progetto.

DTOS

Consiglierei di usare le stesse classi DTO su tutti i livelli. Meno punti di manutenzione in questo modo. Di solito li inserisco in uno MyCompany.MyProject.Modelsspazio dei nomi, nel loro stesso progetto VS con lo stesso nome. E di solito li chiamo semplicemente come l'entità del mondo reale che rappresentano. (Idealmente, anche le tabelle del database usano gli stessi nomi, ma a volte ha senso impostare lo schema in modo leggermente diverso lì.)

Esempi: Person, Address,Product

Dipendenze: nessuna (diversa dalle librerie .NET o helper standard)

DAL

La mia preferenza personale qui è quella di utilizzare un set one-to-one di classi DAL corrispondenti alle classi DTO, ma in uno MyCompany.MyProject.DataAccessspazio dei nomi / progetto. I nomi delle classi qui finiscono con un Enginesuffisso per evitare conflitti. (Se non ti piace quel termine, allora anche un DataAccesssuffisso funzionerebbe bene. Sii coerente con qualunque cosa tu scelga.) Ogni classe fornisce semplici opzioni CRUD che colpiscono il database, usando le classi DTO per la maggior parte dei parametri di input e dei tipi restituiti (all'interno un generico Listquando ce ne sono più di uno, ad esempio il ritorno da un Find()metodo).

Esempi: PersonEngine, AddressEngine,ProductEngine

dipendenze: MyCompany.MyProject.Models

BAL / BLL

Anche qui una mappatura uno a uno, ma in uno MyCompany.MyProject.Logicspazio dei nomi / progetto e con le classi che ottengono un Logicsuffisso. Questo dovrebbe essere l' unico livello che chiama DAL! Le lezioni qui sono spesso un semplice passaggio al DAL, ma se e quando devono essere implementate le regole aziendali, questo è il posto giusto.

Esempi: PersonLogic, AddressLogic,ProductLogic

Dipendenze: MyCompany.MyProject.Models,MyCompany.MyProject.DataAccess

API

Se esiste un livello API dei servizi Web, utilizzo lo stesso approccio uno a uno, ma in uno MyCompany.MyProject.WebApispazio dei nomi / progetto, con Servicesil suffisso della classe. (A meno che non si utilizzi l'API Web ASP.NET, nel qual caso si utilizzerà ovviamente il Controllersuffisso).

Esempi: PersonServices, AddressServices,ProductServices

Dipendenze: MyCompany.MyProject.Models, MyCompany.MyProject.Logic(mai bypass questo chiamando direttamente il DAL!)

Un'osservazione sulla logica aziendale

Sembra essere sempre più comune per le persone lasciare fuori il BAL / BLL e implementare invece la logica di business in uno o più degli altri livelli, ovunque abbia più senso. Se lo fai, sii assolutamente certo che (1) tutto il codice dell'applicazione passa attraverso i livelli con la logica aziendale e (2) è ovvio e / o ben documentato dove è stata implementata ogni particolare regola aziendale. In caso di dubbio, non provarlo a casa.

Una nota finale sull'architettura a livello aziendale

Se ti trovi in ​​una grande azienda o in un'altra situazione in cui le stesse tabelle del database vengono condivise tra più applicazioni, ti consiglio di lasciare la MyProjectparte fuori dagli spazi / progetti sopra elencati. In questo modo quei livelli possono essere condivisi da più applicazioni front-end (e anche da utility dietro le quinte come i servizi di Windows). Ma fallo solo se hai una forte comunicazione tra team e test di regressione automatici accurati in atto !!! In caso contrario, è probabile che le modifiche di una squadra a un componente principale condiviso possano interrompere l'applicazione di un'altra squadra.


2
So che questo è un post antico ma nello spirito del riconoscimento. Volevo solo dire che l'ho trovato utilmente conciso in un argomento che lascia molto al dibattito. Grazie per averlo condiviso!
James Shaw,

7

Di solito costruisco un'applicazione come

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

È in qualche modo simile a Sharp-Lite .

A proposito dei prefissi, li odio. Anche le Linee guida sulla codifica interna di Microsoft li odiano. Inoltre c'è uno strumento chiamato StyleCop che si lamenta anche dei prefissi.


Grazie per il puntatore, ma il mio problema principale è che senza usare i prefissi a volte è difficile capire da quali classi provenga, per esempio ho una classe chiamata da Connection e questo provoca un certo numero di confusioni, mentre se avessi usato un prefisso le cose sarebbero state molto più semplici.
user3631883,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.