Соглашения об именах DAL, BAL и UI Layer [закрыто]

35

Я разрабатываю типичное веб-приложение со следующими слоями

  1. UI Layer (MVC)
  2. Уровень бизнес-логики (BAL)
  3. Уровень доступа к данным (DAL)

Каждый слой имеет свой собственный объект DTO, включая BAL и DAL. Мои вопросы по этому поводу следующие

  1. DTO, возвращенный DAL, просто преобразуется в соответствующий DTO в BAL и отправляется на уровень пользовательского интерфейса. И атрибуты, и структура объектов DTO в некоторых случаях одинаковы. В таких сценариях лучше просто вернуть DTO в DAL на уровень пользовательского интерфейса, не включая промежуточный объект.

  2. Каков наилучший способ назвать эти объекты DTO и другие объекты в каждом слое. Должен ли я использовать какой-то префикс, такой как DTOName, ServiceName? Причина, по которой я прошу использовать префикс, заключается в том, что, если не классы в моем решении конфликтуют с другими классами в Framework и с префиксом, мне легче понять, где принадлежит каждый класс?

user3631883
источник
1
Вы используете пространство имен?
JeffO

Ответы:

48

Предисловие

Надеюсь , это очевидно, но ... в предлагаемых пространств имен ниже, вы бы заменить MyCompanyи MyProjectс реальными именами вашей компании и проекта.

DTOS

Я бы порекомендовал использовать одни и те же классы DTO во всех слоях. Меньше точек обслуживания таким образом. Я обычно помещаю их в MyCompany.MyProject.Modelsпространство имен, в их собственный проект VS с тем же именем. И я обычно называю их просто в честь сущности реального мира, которую они представляют. (В идеале таблицы базы данных тоже используют одинаковые имена, но иногда имеет смысл настроить схему там немного по-другому.)

Примеры: Person, Address,Product

Зависимости: нет (кроме стандартных .NET или вспомогательных библиотек)

DAL

Здесь я предпочитаю использовать набор классов DAL «один к одному», соответствующих классам DTO, но в MyCompany.MyProject.DataAccessпространстве имен / проекте. Имена классов здесь заканчиваются Engineсуффиксом, чтобы избежать конфликтов. (Если вам не нравится этот термин, тогда DataAccessсуффикс тоже будет работать нормально. Просто будьте последовательны с тем, что вы выберете.) Каждый класс предоставляет простые опции CRUD, попадающие в базу данных, используя классы DTO для большинства входных параметров и возвращаемых типов (внутри универсальный, Listкогда их более одного, например, возврат из Find()метода).

Примеры: PersonEngine, AddressEngine,ProductEngine

зависимости: MyCompany.MyProject.Models

BAL / BLL

Также здесь сопоставление один-к-одному, но в MyCompany.MyProject.Logicпространстве имен / проекте, а классы получают Logicсуффикс. Это должен быть единственный слой, который вызывает DAL! Классы здесь довольно часто являются простым переходом к DAL, но если и когда необходимо реализовать бизнес-правила, это место для этого.

Примеры: PersonLogic, AddressLogic,ProductLogic

Зависимости: MyCompany.MyProject.Models,MyCompany.MyProject.DataAccess

API

Если есть уровень API веб-сервисов, я использую тот же подход «один к одному», но в MyCompany.MyProject.WebApiпространстве имен / проекте с Servicesсуффиксом класса. (Если вы не используете ASP.NET Web API, в этом случае вы, конечно, Controllerвместо этого будете использовать суффикс).

Примеры: PersonServices, AddressServices,ProductServices

Зависимости: MyCompany.MyProject.Models, MyCompany.MyProject.Logic(никогда не перепускной это, вызывая DAL непосредственно!)

Наблюдение за бизнес-логикой

Похоже, что все чаще люди опускают BAL / BLL и вместо этого внедряют бизнес-логику на одном или нескольких других уровнях, где бы это ни было наиболее целесообразно. Если вы сделаете это, просто убедитесь, что (1) весь код приложения проходит уровень (уровни) с бизнес-логикой, и (2) это очевидно и / или хорошо задокументировано, где было реализовано каждое конкретное бизнес-правило. Если есть сомнения, не пытайтесь сделать это дома.

Заключительная записка об архитектуре уровня предприятия

Если вы находитесь в большой компании или в другой ситуации, когда одни и те же таблицы базы данных используются несколькими приложениями, я бы порекомендовал MyProjectисключить эту часть из указанных выше пространств имен / проектов. Таким образом, эти слои могут совместно использоваться несколькими интерфейсными приложениями (а также закулисными утилитами, такими как Windows Services). Но делайте это только в том случае, если у вас есть сильная межгрупповая коммуникация и тщательное автоматизированное регрессионное тестирование !!! В противном случае изменения одной команды в компоненте общего ядра могут привести к поломке приложения другой команды.

Трой Джиззи
источник
2
Я знаю, что это древний пост, но в духе признания. Я просто хотел сказать, что я нашел это очень полезным и лаконичным в теме, которая оставляет много вопросов для обсуждения. Спасибо, что поделились этим!
Джеймс Шоу
7

Я обычно строю приложение как

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

Это несколько похоже на Sharp-Lite .

Насчет приставок я их ненавижу. Внутренние правила Microsoft по кодированию также ненавидят их. Также есть инструмент под названием StyleCop, который также жалуется на префиксы.

BrunoLM
источник
Спасибо за указатель, но моя главная проблема заключается в том, что без использования префиксов иногда трудно понять, из каких классов происходит, например, у меня есть класс с именем Connection, и это вызывает ряд недоразумений, тогда как если бы я имел Использовать префикс вещи было бы намного проще.
user3631883