MVC 模型对象、域对象和 DTO 之间的区别是什么

MVC 模型对象、域对象和 DTO 之间的区别是什么?

我的理解是:

MVC 模型对象:

对要由相应视图显示的数据建模。它可能不会直接映射到域对象,即可能包含来自一个或多个域对象的数据。

  1. 客户端
  2. 可能包含业务逻辑。例如,验证,计算属性等
  3. 没有与持久性相关的方法

域对象:

在问题域中建模真实世界对象的对象,如预订、客户、订单等,用于持久化数据。

  1. 服务器端
  2. 没有商业逻辑

数据传输对象(DTO) :

一个对象,用于在层之间传输数据时,层在单独的进程,例如从数据库到客户端应用程序。当获取对应于多个域对象的数据时,允许跨线进行单个事务而不是多个调用。DTO 只包含数据和访问器方法,并且不存在逻辑。数据用于特定的 DB 事务,因此它可能直接映射到域对象,也可能不直接映射到域对象,因为它可能包含来自一个或多个域对象的数据。

  1. 在服务器端和客户端之间传递时使用
  2. 没有商业逻辑
  3. 没有与持久性相关的方法

那么,问题来了:

  1. 以上理解是否正确? 我是否漏掉了一些要点?

  2. 假设 Model 对象不需要额外的业务逻辑,是否有理由不使用 Domain 对象作为 MVC 模型?

  3. 假设 Model 对象不需要额外的业务逻辑,是否有理由不使用 DTO 作为 MVC 模型?

56367 次浏览

The Domain and DTO can also be your "model" objects - you can have a view to render the details of the "Customer" domain object.

A domain object can have business logic to enforce the properties of the domain entity. validation is one such case. The domain object by itself does not contain persistence related methods, but it can have meta-data (like annotations) to support persistence

the POJO programming model makes it possible to use the same object as your domain, DTO and model objects - essentially, you will not be implemented any extraneous interfaces that will only apply to one layer but does not apply to others.

Domain and model objects are essentially the same, and may contain business logic. Depending on implementation, domain and DTO objects may be equivalent if you remove business logic from the model into a service class.

Often a key variant of the DTO is the View Model, which is used purely to transfer data between the domain model and the view, although often a View Model may contain logic, although this should be purely UI logic.

A DTO = is an object that carries data between processes.

But the most interesting part is that, it does not have any behavior except for storage and retrieval of its own data!!!

Sticking with the MVC methodology...

Domain = subject of your entire application.


Model = contains the (programming languages objects : EX: C# objects) to make up the universe of your application.

They can obvioussly have behaviour and properties(see difference with DTO).

Often an application (a light one) can have one model - case in which your model is exactly your domain. Another model can be, a totaly different object type, that is processing another one. Both of them, in this case are part of your domain, and are named "domain models - objects".

Hopefully this answer is exhaustive and makes it all clear for you !

1) No, It is a definition of ViewModel. MVC Model Object and Domain Object both are same.
2) Domain Models (Objects) are always present, business logic is optional
3) If there is no business logic in Domain Object then automatically it becomes DTO.

Any definition for most of the objects is various based on place of using of objects:

Model: is a general definition for using object in client or server.

  1. Model View : is a object using in client most of the time.
  2. Domain Object : is a object using in server and transfering data to the database.
  3. Data Transfer Object(DTO) : is a object that transfer data from one object to another object, specially in getting data in API Call(for example: in api GET Method call for getting data you must not to give database models to client, for this purpose you use dto).

Notice: the definitions are true most of the time but in some situations arent't practical.

My understing (in a big short) is as follows:

(MVC) Model object:

  • represent some things in a some usage context eg. PersonEditModel, PersonViewModel or just PersonModel
  • has no business logic
  • can be subject of some valdation logic etc.
  • used to provide data from one application layer to another eg. MVC Controller <-> MVC View

Domain object:

  • represents some business object (real world object in the problem domain)
  • has business logic
  • do not allow invalid object state, has methods to properly change object's state
  • used to encapsulate business logic related to it
  • have not to be used to persist data (or even should not)

DTO (Data Transfer Object):

  • similar to Model object but should have flat structure
  • only simple type properties/fields (strings, numbers, datetimes, booleans)
  • used to transfer data cross application boundaries eg. between web server and web browser

MVC and DDD can be used together. What we call "Models" both in DDD and MVC are virtually the same: abstractions. Using pseudo-code we can illustrate a few examples.

Model View Controller (MVC)

The Model View Controller ARCHITECTURE separates the software into three parts:

The Model Layer

The Model layer from the MVC Architecture is where the logic resides. In this layer we have our models and business logic.

class Car {


String color;
String year;


Cat(color, year) {
this.color = color;
this.year = year;
}


//getters & setters
}

A simple Car abstraction.

class CarService {


save(car) {
if(car.getColor() != null && car.getYear() != null) {
methodToSave(car);
} else {
throwsException();
}
}


find(car) {
return methodToFind(car);
}


update(car) {
assertThatExists(car);
methodToSave(car);
}


delete(car) {
assertThatExists(car);
methodToDelete(car);
}
}

A simple CRUD for Car using a Service

The View Layer

The View layer is where the user interface resides. Here's where the user can interact with the system, which will then trigger the Controllers on actions performed, which will then inform the Model layer and request data. The View Layer can reside either in the client-side of the application or the server-side of the application (ie: JSF (Java Server Faces) as Server-Side, ReactJS as Client-Side). By any means, even if the View layer resides on the client side, the client will need to request the server-side for sending requests. This may be done by HTTP requests for a Web-Based Application.

<theCarPage>
<theCar>
getTheCarOnLoad();
</theCar>
</theCarPage>

A pseudo-page for the Car.

The Controller Layer

The Controller layer basically receives input from the View and then convert and send the data to the Model Layer and vice-versa.

class CarController {
  

@OnLoadingTheCarPage
getTheCarOnLoad() {
return theCar();
}


}

The method to load the Car.

Domain Driven Design (DDD)

Domain Driven Design is a concept: DDD lays it's foundations in the concept that classes, class variables and class methods must match it's core business domain.

Domain Driven Design Resides into the "M"

In this case, when MVC is applied, the Domain Driven Design resides into the Model Layer of the MVC Architecture. As explained before, the Model Layer is where the Business Logic of the application resides.

Either if you have entities or not, they still are Models. A Model is just an abstraction of something in the real world. A cat can be a Model if abstracted:

class Cat {
  

String color;
String age;


Cat(color, age) {
this.color = color;
this.age = age;
}


//getters & setters
}

Simple Cat abstraction. It is a Model of Cat.

DDD Entities

In Domain Driven Design we have Entities, that are also classified as Models. The difference between them is that Entities are identifiable. If you have a class that is identifiable and can be persisted, then it's an Entity. An Entity still, is a Model.

@AnEntity
@ThisCanBePersisted
class Cat {
  

@ThisIsAnId
@ThisValueIncrementsAutomatically
@PersistentProperty
Long id;
@PersistentProperty
String color;
@PersistentProperty
String age;


Cat(color, age) {
this.color = color;
this.age = age;
}


//getters & setters
}

A simple Entity. An Entity is a Model.

Data Transfer Objects (DTO)

Data Transfer Objects have no logic inside them and the only use to them is to be containers for transferring data from one endpoint to another. Usually Enterprise Entities are not Serializable by nature, so we need a way to send only the data that we need to be sent to a client. Since a Model could have sensible data or simply data we don't want to share in a request for a fetch, for instance, then considering our Cat Model, we could create a DTO that does not share the Cat's ID:

class CatDTO {


String color;
String age;


//getters & setters
}

A Data Transfer Object for Cat. We only need it's properties and something to get and set the properties. We don't want to share it's ID.

So if we, for instance, had to request a list of all cats from our client using REST, then we would request the endpoint that responds with our CatDTO instead of our Cat Entity:

[
Cat {
"color": "yellow",
"age": "1"
},
Cat {
"color": "black",
"age": "4"
}
]

And that would be all the data that our client could see.