Объекты VS Модели доменов VS View Models

Есть сотни подобных вопросов по этой теме. Но я все еще смущен, и я бы хотел, чтобы эксперты посоветовали об этом.

Мы разрабатываем приложение с использованием ASP.NET MVC 4 и EF5, а наш подход - к DB.

У нас есть уровень данных в отдельном проекте, который является библиотекой классов и содержит все Определенные в нем объекты. И тогда бизнес-уровень определяется всеми репозиториями и моделями доменов (это правильный термин для использования). А затем появляется уровень представления.

В настоящее время мы не определили какие-либо модели представлений, мы используем одни и те же модели домена из BL в качестве моделей представлений. При таком подходе может быть достаточно одного отображения.

ENTITY <= > ДОМЕННАЯ МОДЕЛЬ

Но для меня это не похоже на хороший дизайн. Я предпочитаю иметь модели представления, определенные на моем уровне представления, и использовать модели домена для связи между уровнем представления и бизнес-уровнем. И в BL, конвертировать объекты домена в объекты данных и связываться с DAL. Используя этот подход, я должен использовать отображение дважды.

Показать модель <= > DOMAIN MODEL <= > ENTITY

Действительно ли нужна моя модель домена? Не могу ли я использовать свой объект для связи с уровнем Presentation. Есть ли какие-либо последствия, если я ссылаюсь на Entities в моем слое представления? Если есть какие-то последствия?

Ответ 1

Я думаю, что у вас просто проблемы с определением того, что каждый слой и какую роль он играет в вашем решении.


Уровень данных

Ваш уровень данных - это просто ваша база данных/список SharePoint/.csv/excel sheet... вы получаете идею, она просто там, где хранятся ваши данные, и может быть в любом формате. Поэтому помните, что уровень данных - это не что иное, как просто данные.

// ----------------------------
//    Data tier
//        - MySQL
//        - MS SQL
//        - SharePoint list
//        - Excel
//        - CSV
//        - NoSQL
// ----------------------------

Уровень доступа к данным

Этот слой абстрагирует ваш источник данных и предоставляет API, в котором остальная часть вашего приложения может взаимодействовать с источником данных.

Учтите, что наш источник данных - это база данных MS SQL, и мы используем Entity Framework для доступа к данным. То, что вы будете пытаться абстрагироваться, - это база данных и Entity Framework, а для Entity - Data Repository.

Пример...

У нас есть таблица Customers в базе данных MS SQL. Каждый клиент в таблице клиентов является Entity и представляется как таковой в вашем коде С#.

Используя шаблон репозитория, мы можем абстрагироваться от реализации кода доступа к данным, так что в будущем, если наш источник данных изменится, остальное наше приложение не будет затронуто. Далее нам понадобится CustomersRepository в нашем Data Access Layer, который будет включать такие методы, как Add, Remove и FindById. Отвлечь любой код доступа к данным. Ниже приведен пример того, как вы достигнете этого.

public interface IEntity
{
    int Id { get; set; }
}

public class Customer : IEntity
{
    public int Id { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public DateTime RegistrationDate { get; set; }
}

public interface IRepository<TEntity> where TEntity : class, IEntity
{
    TEntity FindById(int id);

    void Add(TEntity entity);

    void Remove(TEntity entity);
}

public class CustomerRepository : IRepository<Customer>
{
    public Customer FindById(int id)
    {
        // find the customer using their id
        return null;
    }

    public void Add(Customer customer)
    {
        // add the specified customer to the db
    }

    public void Remove(Customer customer)
    {
        // remove the specified customer from the db
    }
}

Уровень доступа к данным находится между слоем данных и бизнес-логикой.

// ----------------------------
//    Business logic
// ----------------------------

// ----------------------------
//    Data access layer
//        - Repository 
//        - Domain models / Business models / Entities
// ----------------------------

// ----------------------------
//    Data tier
//        - MySQL
//        - MS SQL
//        - SharePoint list
//        - Excel
//        - CSV
//        - NoSQL
// ----------------------------

Бизнес-уровень

Бизнес-уровень построен поверх уровня доступа к данным и не касается проблем с доступом к данным, но строго бизнес-логики. Если одним из бизнес-требований было предотвращение заказов из-за пределов Великобритании, тогда уровень бизнес-логики справился бы с этим.


Уровень представления

Уровень презентации просто представляет ваши данные, но если вы не будете осторожны в отношении того, какие данные вы представляете, и какие данные вы позволяете размещать, вы ставите себя на множество головных болей по линии, что поэтому важно использовать модели просмотра, поскольку модели представления представляют собой проблему уровня представления, уровень представления не должен ничего знать о ваших моделях домена, он должен знать только о моделях представлений.

Итак, что такое View Models... Это просто модели данных, которые настроены для каждого представления, например, форма регистрации будет включать RegistrationViewModel, отображая эти типичные свойства.

public class RegistrationViewModel
{
    public string Email { get; set; }
    public string Password { get; set; }
    public string ConfirmPassword { get; set; }
}

Уровень представления также обрабатывает проверку ввода, поэтому, например, проверка правильности формата адреса электронной почты или совпадение паролей представляет собой проблему уровня представления, а не деловую проблему, и ее можно обрабатывать с помощью Data Annotations.

public class RegistrationViewModel
{
    [Required]
    [DataType(DataType.EmailAddress)]
    public string Email { get; set; }

    [Required]
    [DataType(DataType.Password)]
    [Compare("ConfirmPassword")
    public string Password { get; set; }

    [Required]
    [DataType(DataType.Password)]
    public string ConfirmPassword { get; set; }
}

Причина, по которой важно использовать модели просмотра, заключается в том, что бизнес-модели относятся к бизнес-уровню, и они включают данные, которые должны оставаться конфиденциальными. Например, если вы должны были отобразить модель домена в ответе JSON, это разоблачит все данные пользователей, их имя будет их адресом, поскольку вы не будете избирательным в отношении того, что подвергается, а что нет, но используя все, что кажется, работает.


Здесь также следует указать, что существует разница между domain models и entity models. Там уже есть ответ, который будет намного подробнее здесь


Проблемы с поперечной средой

Я буду держать это сообщение:

  • Управление исключениями
  • Сопоставление моделей моделей с моделями.

Ответ 2

Я не эксперт, но я поделюсь своими 50 центами на эту тему.

Показать модель

Я хотел бы поделиться вашей озабоченностью по поводу игнорирования View Model.

Используя модель просмотра, вы можете:

  • Выберите только данные, необходимые для модели домена
  • Отформатируйте нужные данные в представлении (например, формат десятичного числа (100,00) в строку (100,00 евро))
  • Вы можете использовать DataAnnotation в своей модели просмотра.

Итак, я также считаю это плохой дизайн, но другие могут иметь другое мнение.

Помните, что бизнес-уровень ничего не знает о модели представления, поэтому вы должны сопоставить его в контроллере.

Объекты и модель домена

Я бы начал просто, используя POCO в качестве модели домена, которая может сохраняться с ORM или NoRM. Для большинства программ, разработанных в мире, это не повредит вашей системе, и это также просто.

В будущем, если вы по какой-то причине начнете использовать веб-службы, возможно, вам придется рассмотреть возможность использования DTO (объектов передачи данных) для удаленных вызовов. Когда там, что вы можете сделать, это иметь еще один слой, отвечающий за сопоставление модели домена с желаемым DTO. Этот уровень будет использоваться только в удаленном вызове (веб-служба), сохраняя модель представления для презентации.

Ответ 3

Основным преимуществом введения дополнительных классов является разделение проблем:

  • Уровень представления: отображение информации и ввода данных, включая любые предварительные и постобработки для достижения этого, например. форматирования.
  • Логика домена/бизнеса/приложения: здесь выполняется фактическая работа.
  • Уровень сохранения: сохранение и извлечение данных

Это может быть достигнуто только с двумя классами модели для ViewModels и Domain Entities. Вместо моделирования логики домена с отдельными классами моделей, которые аналогичны сохраняемым объектам, реализуйте их в классах служб, которые потребляют объекты домена. У объектов домена не должно быть логики, которая имеет свои собственные свойства (например, чтобы сохранить объединенные значения двух свойств в допустимом состоянии). Если на какой-либо объект домена влияет пользовательская система, создайте эту утилиту в классе обслуживания. Если вы поместите логику для управления отношениями между объектами непосредственно в классах сущностей, код становится незаметным очень быстро (поверьте, я попытался).

Я не рекомендую использовать устойчивые объекты как ViewModels, потому что это будет смешивать проблемы отображения (например, [DisplayName]) с проблемами сохранения (например, [ForeignKey]).