实体 VS 领域模型 VS 视图模型 [英] Entities VS Domain Models VS View Models

查看:27
本文介绍了实体 VS 领域模型 VS 视图模型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

关于这个主题有数百个类似的问题.但我仍然很困惑,我想就此获得专家的建议.

There are hundreds of similar questions on this topic. But I am still confused and I would like to get experts advise on this.

我们正在使用 ASP.NET MVC 4 和 EF5 开发应用程序,我们采用的是 DB 优先方法.

We are developing an application using ASP.NET MVC 4 and EF5 and ours is DB first approach.

我们在一个单独的项目中有数据层,它是一个类库,并包含其中定义的所有实体.然后使用所有存储库和域模型定义业务层(这是要使用的正确术语).然后是表现层.

We have Data layer in a separate project which is a class library and holds all the Entities defined in it. And then Business Layer defined with all the repositories and domain models(is that right term to be used). And then comes presentation layer.

目前我们还没有定义任何视图模型,我们使用来自 BL 的相同域模型作为视图模型.在这种方法中,一个映射就足够了.

At present we have not defined any view models, we are using the same domain models from BL as view models. In this approach one mapping can be enough.

实体 <=> 域模型

但对我来说,这看起来不是一个好的设计.我更喜欢在表示层中定义视图模型,并使用域模型在表示层和业务层之间进行通信.在 BL,将域对象转换为数据实体并与 DAL 进行通信.使用这种方法我必须使用映射两次.

But for me it's not looking like a good design. I prefer to have view models defined in my presentation layer and use domain models to communicate between presentation layer and business layer. And at BL, convert domain objects to data entities and communicate with DAL. Using this approach I have to use mapping twice.

查看模型<=>域模型<=>实体

View Model <=> DOMAIN MODEL <=> ENTITY

我的领域模型真的有必要吗?我不能使用我的实体与表示层进行通信.如果我在表示层中引用实体,会有什么影响吗?如果有什么样的影响?

Is my domain model really necessary? Can't I use my entity to communicate with Presentation layer. Are there any impacts if I am referencing Entities in my presentation layer? If there are what kind of impacts?

推荐答案

我认为您只是在定义每一层是什么以及它在您的解决方案中扮演什么角色时遇到问题.

I think you're just having issues with defining what each layer is and what role it is playing in your solution.

您的数据层就是您的数据库/SharePoint 列表/.csv 文件/Excel 表格……您明白了,它只是您数据的存储位置,并且可以是任何格式.所以请记住,数据层只不过是数据.

Your data tier is simply your database / SharePoint list / .csv file / excel sheet... you get the idea, it's simply where your data is stored, and it can be in any format. So remember that the data tier is nothing more than just data.

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


数据访问层

该层抽象出您的数据源,并提供一个 API,您的应用程序的其余部分可以在其中与数据源进行交互.


Data Access Layer

This layer abstracts away your data source, and provides an API in which the rest of your application can interact with the data source.

考虑到我们的数据源是 MS SQL 数据库,并且我们使用实体框架来访问数据.您将尝试抽象的是数据库和实体框架,并为每个 Entity 设置一个 Data Repository.

Consider that our data source is an MS SQL Database and that we're using Entity Framework to access the data. What you'll be attempting to abstract away, is the database and Entity Framework, and have a Data Repository for each Entity.

我们在 MS SQL 数据库中有一个 Customers 表.客户表中的每个客户都是一个 Entity ,并在您的 C# 代码中如此表示.

We have a Customers table in a MS SQL Database. Each customer in the customers table is an Entity , and is represented as such in your C# code.

通过使用存储库模式,我们可以抽象出数据访问代码的实现,以便将来如果我们的数据源发生变化,我们应用程序的其余部分不会受到影响.接下来,我们需要在 Data Access Layer 中添加一个 CustomersRepository,其中包括诸如 AddRemoveFindById.抽象掉任何数据访问代码.下面的示例是您将如何实现这一目标.

By using the repository pattern, we can abstract away the implementation of the data access code, so that in future, if our data source changes, the rest of our application wont be affected. Next we would need a CustomersRepository in our Data Access Layer, which would include methods such as Add, Remove and FindById. To abstract away any data access code. The example below is how you would achieve this.

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
    }
}

数据访问层介于数据层和业务逻辑之间.

The data access layer belongs in between the data layer and business logic.

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

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

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


业务层

业务层建立在数据访问层之上,不处理任何数据访问问题,而是严格的业务逻辑.如果业务要求之一是防止来自英国以外的订单,那么业务逻辑层会处理这个问题.


Business layer

The business layer is built on top of the data access layer, and does not deal with any data access concerns, but strictly business logic. If one of the business requirements was to prevent orders being made from outside of the UK, then the business logic layer would handle this.

展示层只是展示您的数据,但是如果您不注意展示的数据以及允许发布的数据,那么您就会为自己设置很多麻烦,这就是这就是为什么使用视图模型很重要的原因,因为视图模型是表示层关注的问题,表示层不需要了解您的域模型的任何信息,它只需要了解视图模型.

The presentation tier simply presents your data, but if you're not careful about what data you present, and what data you allow to be posted, you'll set your self up for a lot of headaches down the line, which is why it's important to use view models, as view models are a presentation tier concern, the presentation tier doesn't need to know anything about your domain models, it only needs to know about view models.

那么什么是视图模型...它们只是为每个视图量身定制的数据模型,例如一个注册表将包含一个 RegistrationViewModel,暴露这些典型的属性.

So what are View Models... They're simply data models which are tailored for each view, for example a registration form would include a RegistrationViewModel, exposing these typical properties.

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

表示层还处理输入验证,例如验证输入的电子邮件地址是否具有正确的格式,或者输入的密码是否匹配是表示层的问题,而不是业务问题,并且可以使用 数据注释.

The presentation tier also handles input validation, so for instance validating whether an email address typed has the correct format, or that the passwords entered match is a presentation tier concern, not a business concern, and can be handled by using 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 响应中公开域模型,它将公开用户的整个数据,他们命名他们的地址,因为您没有选择公开什么和不公开什么,而是使用任何内容似乎正在工作.

The reason it's important to use View Models is because the Business Models belong to the business layer, and they include data which should remain private. For instance, if you were to expose the Domain Model in a JSON response, it would expose the users entire data, their name their address as you're not being selective about what is being exposed and what isn't, but using whatever that seems to be working.

我还应该在这里指出领域模型实体模型之间的区别.已经有一个更详细的答案 这里

I should also point out here that there is a difference between domain models and entity models. There's already an answer that goes into a lot more detail here

我会保持简短:

  • 异常管理
  • 将视图模型映射到域模型.

    这篇关于实体 VS 领域模型 VS 视图模型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆