Konwencje nazewnictwa DAL, BAL i warstwa interfejsu użytkownika [zamknięte]

35

Tworzę typową aplikację internetową z następującymi warstwami

  1. Warstwa interfejsu użytkownika (MVC)
  2. Warstwa logiki biznesowej (BAL)
  3. Warstwa dostępu do danych (DAL)

Każda warstwa ma swój własny obiekt DTO, w tym BAL i DAL. Moje pytania dotyczące tego są następujące

  1. DTO zwrócone przez DAL jest po prostu konwertowane do odpowiedniego DTO w BAL i wysyłane do warstwy interfejsu użytkownika. Zarówno atrybuty, jak i struktura obiektów DTO są w niektórych przypadkach takie same. W takich scenariuszach lepiej jest po prostu przywrócić DTO z DAL do warstwy interfejsu użytkownika bez uwzględnienia obiektu pośredniego.

  2. Jaki jest najlepszy sposób nazwania tych obiektów DTO i innych obiektów w każdej warstwie. Czy powinienem użyć jakiegoś przedrostka, takiego jak DTOName, ServiceName? Powód, dla którego proszę o użycie prefiksu, jest taki, że jeśli nie, klasy w moim Rozwiązaniu kolidują z innymi klasami w Framework, a wraz z prefiksem łatwiej jest mi zrozumieć, gdzie należy każda klasa?

użytkownik3631883
źródło
1
Czy używasz przestrzeni nazw?
JeffO

Odpowiedzi:

48

Przedmowa

Mam nadzieję, że jest to oczywiste, ale ... w sugerowanych nazw poniżej, należy wymienić MyCompanyi MyProjectz rzeczywistymi nazwami firmy i projektu.

DTO

Poleciłbym stosowanie tych samych klas DTO na wszystkich warstwach. W ten sposób mniej punktów konserwacji. Zazwyczaj umieszczam je pod MyCompany.MyProject.Modelsprzestrzenią nazw, w ich własnym projekcie VS o tej samej nazwie. I zazwyczaj nazywam je po prostu bytem z prawdziwego świata, który reprezentują. (Najlepiej, jeśli tabele bazy danych również używają tych samych nazw, ale czasem sensowne jest ustawienie tam schematu nieco inaczej).

Przykłady: Person, Address,Product

Zależności: Brak (inne niż standardowe biblioteki .NET lub biblioteki pomocnicze)

DAL

Osobiście preferuję tutaj zestaw klas DAL jeden do jednego pasujący do klas DTO, ale w MyCompany.MyProject.DataAccessprzestrzeni nazw / projekcie. Nazwy klas tutaj kończą się Engineprzyrostkiem, aby uniknąć konfliktów. (Jeśli nie podoba ci się ten termin, DataAccesssufiks też by działał. Po prostu zachowaj spójność z tym, co wybierzesz.) Każda klasa zapewnia proste opcje CRUD uderzające w bazę danych, przy użyciu klas DTO dla większości parametrów wejściowych i typów zwracanych (wewnątrz rodzajowy, Listgdy występuje więcej niż jeden, np. zwrot z Find()metody).

Przykłady: PersonEngine, AddressEngine,ProductEngine

Zależności: MyCompany.MyProject.Models

BAL / BLL

Także tutaj mapowanie jeden do jednego, ale w MyCompany.MyProject.Logicprzestrzeni nazw / projekcie, z klasami uzyskującymi Logicprzyrostek. To powinna być jedyna warstwa, która wywołuje DAL! Zajęcia tutaj są często zwykłym przejściem do DAL, ale jeśli i kiedy trzeba wdrożyć reguły biznesowe, jest to miejsce na to.

Przykłady: PersonLogic, AddressLogic,ProductLogic

Zależności: MyCompany.MyProject.Models,MyCompany.MyProject.DataAccess

API

Jeśli istnieje warstwa interfejsu API usług internetowych, używam tego samego podejścia jeden do jednego, ale w MyCompany.MyProject.WebApiprzestrzeni nazw / projekcie, z Servicessufiksem klasy. (O ile nie korzystasz z interfejsu API sieci Web ASP.NET, w takim przypadku należy oczywiście użyć Controllersufiksu).

Przykłady: PersonServices, AddressServices,ProductServices

Zależności: MyCompany.MyProject.Models, MyCompany.MyProject.Logic(nigdy bypass to poprzez wywołanie DAL bezpośrednio!)

Obserwacja logiki biznesowej

Wydaje się, że coraz częściej ludzie pomijają BAL / BLL i zamiast tego wdrażają logikę biznesową na jednej lub kilku innych warstwach, tam gdzie ma to sens. Jeśli to zrobisz, bądź absolutnie pewien, że (1) cały kod aplikacji przechodzi przez warstwę z logiką biznesową i (2) jest oczywiste i / lub dobrze udokumentowane, gdzie wdrożono każdą regułę biznesową. W razie wątpliwości nie próbuj tego w domu.

Ostatnia uwaga na temat architektury na poziomie przedsiębiorstwa

Jeśli jesteś w dużej firmie lub w innej sytuacji, w której te same tabele bazy danych są współużytkowane przez wiele aplikacji, zaleciłbym pozostawienie tej MyProjectczęści poza powyższymi przestrzeniami nazw / projektami. W ten sposób warstwy te mogą być współużytkowane przez wiele aplikacji typu front-end (a także narzędzia zakulisowe, takie jak Windows Services). Ale rób to tylko, jeśli masz silną komunikację między zespołami i dokładne automatyczne testy regresji! W przeciwnym razie zmiany jednego zespołu we wspólnym podstawowym komponencie mogą zepsuć aplikację innego zespołu.

Troy Gizzi
źródło
2
Wiem, że to starożytny post, ale w duchu uznania. Chciałem tylko powiedzieć, że uznałem to za użyteczne zwięzłe w temacie, który pozostawia wiele do dyskusji. Dziękujemy za udostępnienie tego!
James Shaw
7

Zwykle tworzę aplikację jako

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

Jest nieco podobny do Sharp-Lite .

Jeśli chodzi o prefiksy, nienawidzę ich. Nienawidzą ich także wewnętrzne wytyczne Microsoft dotyczące kodowania . Istnieje również narzędzie o nazwie StyleCop, które również skarży się na prefiksy.

BrunoLM
źródło
Dzięki za wskaźnik, ale moim głównym problemem jest to, że bez użycia prefiksów czasami trudno jest ustalić, z których klas jest, skąd np. Mam klasę wywoływaną z Connection, co powoduje szereg nieporozumień, podczas gdy gdybym miał użyłem prefiksu rzeczy byłyby znacznie prostsze.
user3631883,