After a comment of this question. I started to research but I am still confused.
Entities should convert to Dto before return to controller? To me it sounds not really practical.
We are talking about software architecture and as always when we are talking about software architecture there are a thousand ways of doing something and many opinions about what is the best way. But there is no best way, everything has advantages and disadvantages. Keep this in mind!
Typically you have different layers:
A persistence layer to store data
Business layer to operate on data
A presentation layer to expose data
Typically, each layer would use its own kind of objects:
Persistence Layer: Repositories, Entities
Business Layer: Services, Domain Objects
Presentation Layer: Controllers, DTOs
This means each layer would only work with its own objects and never ever pass them to another layer.
Why? Because you want each layer to be separated from the other layers. If you would use entities in your controller, your presentation would depend on how your data is stored. That's really bad. Your view has nothing to do with how the data is stored. It shouldn't even know that or how data is stored.
Think of that: You change your database model, e.g. you add a new column to one of your database tables. If you pass the entities to your controller (or worse: your controller exposes them as JSON), a change at the database would result in a change in your presentation. If the entities are directly exposed as JSON, this might even result in changes in JavaScript or some other clients which are using the JSON. So a simple change in the database might require a change in the JavaScript front end, because you couple your layers very tight. You definitely don't want that in a real project.
How? You doubt that this is practical, so just a small example of how to do that in (pseudo) code:
class Repository {
public Person loadById(Long id) {
PersonEntity entity = loadEntityById(id);
Person person = new Person();
person.setId(entity.getId());
person.setName(entity.getFirstName + " " + entity.getLastName());
return person;
}
}
In this example, your repository would use entities internally. No other layer knows or uses this entities! They are an implementation detail of this particular layer. So if the repository is asked to return a "person", it works on the entity, but it will return a domain object. So the domain layer which works with the repo is save in the case the entities need to be changed. And as you can see in the case of the name, the domain and the database might be different. While the database stores the name in first name and last name, the domain only know a single name. It's a detail of the persistence how it stores the name.
The same goes for controllers and DTOs, just another layer.
Related
In my app I have my domain layer and web interface (other layers I will not go into details).
My views, working with ViewModels objects, and the database persist domain objects.
To convert a ViewModel object to a domain object I use AutoMapper.
The problem with the working Breeze is that when I will create a new object var newCust = manager.createEntity('Customer', {name:'Beta'}) this is a domain object, and should be an ViewModel object.
Not all, but in some cases the ViewModel is not similar to the object domain. For example, collections of objects in the domain are: ICollection<Person> while in view model are ICollection<int> int is a PK of person.
Question
How to working with breeze in these cases?
How to make the metadata also manages the structure of my viewmodels so I can create objects of type my ViewModel?
#ridermansb - Because you mentioned AutoMapper, I will assume that your mapping is taking place on the server. You want your server API to expose "ViewModels" (in this case you might call them DTOs) rather than the domain model objects. Sometimes your ViewModels mirror your domain objects exactly; sometimes they don't.
Your client only sees what your API exposes. If this is a BreezeJS client, you will likely treat the ViewModels as client-side entities. They are Breeze entities in the sense that you expect Breeze to query, cache, change-track, and validate them. BreezeJS doesn't know whether these "entities" correspond to server-side DTOs or server-side business objects.
Of course if you're using DTOs/ViewModels, your server code is responsible for translating between the DTO form and the domain object form. Presumably this logic lies somewhere in/between the server-side API layer and the domain layer.
If you have chosen this architecture, you have chosen to deal with the bi-directional translation between ViewModels and domain objects and have embraced all the complexity and hassle that entails. I have no words of advice for you on that score.
So let me rephrase and narrow your question: "How can I get metadata that describe the object model exposed by my server-side API?"
My favorite way (assuming a .NET server) is to let EF do it for me. I create a DbContext that references NOT my domain model classes but rather my ViewModel/DTO classes. Of course these classes would not actually map to a real database. No problem; they don't have to. You will never use this DbContext to access data. You will only use it to generate metadata. You are using EF as a design-time, metadata-generating tool ... and that's it. This is an efficient maintainable approach.
I hope to demonstrate this technique "soon" but I've been mighty busy recently so no promises.
Alternatively, you can write the metadata by hand as described here.
This question really has larger architectural implications and I welcome any input or suggestions on this:
I'm more of the Martin Fowler school of thought when it comes to OOP. I believe you should be able to directly render domain entities in the UI. If I have a Car entity, I should be able to render it to a webpage. The domain model is a crosscutting concern and not a layer. Treating the domain model as a layer leads to an anemic domain model. I don't believe in DTOs in an OOP architecture.
A view model for me is a way of composing the domain entities required in your view. It's not a DTO. I don't understand what the reasoning behind using a view model like DTO is though it seems like a common thing to do using automapper?
So using the metadata approach I put data annotations on my domain model to give any UI implementation hints on how to render and validate the entities. I like to have a richER domain model.
In MVC3 how can you accomplish this (specifically using the Display data annotation) with a resource file that resides in the UI layer? Is there a native implementation for this or do I need to get creative myself? Or have I gone wrong somewhere in my approach?
I disagree.
For one thing, some of the attributes you will use to specify how an entity property should be displayed on a web page come from the System.Web namespace, not the System.ComponentModel.DataAnnotations namespace. By putting these attributes on properties in your domain model, your domain model is taking a dependency on System.Web. For example, there is the [HiddenInput] attribute that tells MVC3 to render a field as input type="hidden". This is not in System.CompoenentModel.DataAnnotations.
Secondly, I don't believe you need data annotation attributes on your entity properties to have a rich domain model. A rich domain model comes from classes that wrap knowledge in a context. The client application should not need to know anything about the domain in order to use it. You achieve a rich domain model with classes, methods, and properties that describe knowledge using the ubiquitous language. DataAnnotations attributes don't lend themselves well to the ubiquitous language imo. And, your domain is more than just your entities. There are factories, services, and other patterns that you can use to build a rich domain model. A domain with only entities and metadata sounds anemic to me.
Thirdly, you may have an entity that should be rendered in different ways on your web site. When someone searches for a car, you may want to display just the make, model, year, and thumbnail photo. When someone clicks on the search result, you may want to display multiple photos, reviews, etc. If you were to use the UIHint attribute on an entity to tell the web ui how to render the car, you wouldn't be able to have different strategies for rendering the Car in different contexts.
Finally, yes, automapper is really great for DTOing your entities into viewmodels. It essentially lets you populate copies of the entity, disconnected from the domain, targeted for specific UI concerns. Here it is safe to use HiddenInput and UIHint attributes to tell MVC3 how to render data.
Response to comment 1
As far as UIHint, I mentioned it here because it has a special meaning with MVC3 EditorTemplates. In cases where a partial view involves receiving input, what is the composition of the view? Text fields, drop-down lists, and input elements that often correspond to entities and their properties in some aggregate root. You will therefore need some representation of the entities to encapsulate the data. Your DTO can be an aggregate root as well, with depth. You can have a root DTO with scalar properties (text/date/bool), navigation properties (drop-down list) and collection properties (ul/ol/table).
We create a corresponding viewmodels for many entities in an aggregate root, and implement them as views using EditorTemplates. If we ever want to switch to a different EditorTemplate, we can apply UIHint to a viewmodel property. Thus we can tell it to "render a location dto as a google map". Automapper can map navigational and collection properties to corresponding viewmodels, forming as complex a representation of your domain entities as you need for the user.
Forgive me if I misunderstand what you mean by flat dto.
Response to comment 2
A viewmodel dto can flatten out / denormalize some properties (using automapper), if your requirements call for it. For example, consider a University entity. It may have many names in many languages (translations), hinting at a UniversityName entity in the aggregate, with University having a collection of Names (1..n). Of those names, 1 may represent the OfficialName / NativeName, and another may represent the TranslatedName to the user's CurrentUICulture. Other entities in the collection may represent TranslatedNames that the user does not understand, and need not be bothered with.
If you have a view that is only interested in these 2 Names in the collection, you can promote them to first-class properties on the viewmodel:
public class UniversityViewModel
{
public string OfficialName { get; set; }
public string TranslatedName { get; set; }
// ...other properties
}
This is a case where denormalizing part of the entity when converting to a viewmodel dto can make sense. Notice how the viewmodel is anemic -- a bare container for data transfer from a controller to a view. This is perfectly fine, and in fact, encouraged.
Answer to original question
To answer your original question, it helps if you think of your domain model & entities as a layer -- more specifically, a bottom layer. Layered software is easier to understand if you think about the various concerns in an application as having dependencies on other concerns. MVC3 is a presentation / UI layer, and will have dependencies on the layers beneath it -- one of those being your domain layer.
If you want to access a resource file in the UI from the domain layer, you are going in the opposite direction. You would be making a low layer depend on a higher layer. If your domain lib depends on the UI lib for a resource, and the UI lib depends on the domain for entities, you end up with a circular dependency. I think you could probably accomplish it using reflection if you needed to, but in that case, you would be fighting against the framework. MVC and .NET in general may not be the best choice for you if that is the case.
I actually think of resource files as a cross-cutting concern. Our application has i18n sprinkled throughout, and often we find we need the same language text resources in both the domain and the UI.
There is nothing wrong with putting a Display attribute on an entity. But if you want to use resources for it, then either put that resource in the domain layer, or if you feel it doesn't belong there, in a lower layer. That way it can be accessed by both the domain and the UI.
So I ended up putting a resourse file in the domain model and added a custom HiddenFieldAttribute so that I don't have to reference the MVC assembly in the domain model.
I still fundamentally dissagree that a view model is really a DTO and that the domain model should be constructed as a layer. I feel that architecting the application in this way creates abstractions that really have no value. If the domain model was truly a layer then we would build a set of logical interfaces from which to access it, and this we don't do. It's a cross cutting concern.
Thanks to olivehour for an interesting discussion and suggesting that it's okay to place resource file(s) in to domain model assembly.
suppose you have an MVC application with the Model represented by an Entity Framework (EF) that "gets" data from a database and the action methods of the Controller that implements all the business logic. The Controller gets data from the database through the EF.
Imagine that now you create a Repository class that is placed between Controller and Model. This way you have:
1) Controller: implements most of the business logic;
2) A Repository class, responsible to implement simple business logic, provide data to every Controller in the application through methods and get data from the EF;
3) Model: EF classes that gets data from the database and provide them to the Repository class.
Is the Repository class the business service layer or there is the need to add a business layer placed between controllers and repository? In this latter situation we have:
1) Controllers: implements just the request elaboration;
2) Business layer: a set of classes responsible to implement most of the business logic and provide data to every Controller in the application through methods;
3) A Repository class: gets data from the EF and expose methods to the Business layer for querying the database;
4) Model: EF classes that "get" data from the database and provide them to the Repository class.
I do not consider the View because it is not relevant. I hope somebody can make clear for me this distinction. Many thanks
Cheers
Francesco
The definitions you have proposed for Model and Controller differ from the traditional usages of the terms in the MVC pattern - or at least, the pattern as defined by Martin Fowler here.
Usually it is the Model that contains most of the business logic, and the Controller is responsible for managing the flow of information between the View and the Model. To quote from Fowler's article:
The controller's job is to take the
user's input and figure out what to do
with it.
Looking at your actual question with regard to where a Repository should be placed, it would be within the Model, but encapsulated away as part of your data access infrastructure (that is almost the very definition of what a Repository is).
So the Model becomes made up of two key parts - Domain objects which have expressive business logic, and service infrastructure that does things like accessing the data access layer. (Another common approach is to have the Model made up of services which don't really feature a rich domain model, but still this contains all business logic and data access).
One last thought is be careful about over thinking or abstracting this stuff - keep it as simple as possible and only introduce a new layer to your architecture when you are sure it will give value. For example - EF itself can perform the role of your Repository in most scenarios, so using it directly without the repository layer can remove an unnecessary abstraction.
I'm slightly confused about what exactly the Model is limited to. I understand that it works with data from a database and such. Can it be used for anything else though? Take for example an authentication system that sends out an activation email to a user when they register. Where would be the most suitable place to put the code for the email? Would a model be appropriate... or is it better put in a view, controller, etc?
Think of it like this. You're designing your application, and you know according to the roadmap that version 1 will have nothing but a text based command line interface. version 2 will have a web based interface, and version 3 will use some kind of gui api, such as the windows api, or cocoa, or some kind of cross platform toolkit. It doesn't matter.
The program will probably have to go across to different platforms too, so they will have different email subsystems they will need to work with.
The model is the portion of the program that does not change across these different versions. It forms the logical core that does the actual work of whatever special thing that the program does.
You can think of the controller as a message translator. it has interfaces on two sides, one faces towards the model, and one faces towards the view. When you make your different versions, the main activity will be rewriting the view, and altering one side of the controller to interface with the view.
You can put other platform/version specific things into the controller as well.
In essense, the job of the controller is to help you decouple the domain logic that's in the model, from whatever platform specific junk you dump into the view, or in other modules.
So to figure out whether something goes in the model or not, ask yourself the question "If I had to rewrite this application to work on platform X, would I have to rewrite that part?" If the answer is yes, keep it out of the model. If the answer is no, it may go into the model, if it's part of the essential logic of the program.
This answer might not be orthodox, but it's the only way I've ever found to think of the MVC paradigm that doesn't make my brain melt out of my ear from the meaningless theoretical mumbo jumbo that discussions about MVC are so full of.
Great question. I've asked this same question many times in my early MVC days. It's a difficult question to answer succintly, but I'll do my best.
The model does generally represent the "data" of your application. This does not limit you to a database however. Your data could be an XML file, a web resource, or many other things. The model is what encapsulates and provides access to this data. In an OOP language, this is typically represented as an object, or a collection of objects.
I'll use the following simple example throughout this answer, I will refer to this type of object as an Entity:
<?php
class Person
{
protected $_id;
protected $_firstName;
protected $_lastName;
protected $_phoneNumber;
}
In the simplest of applications, say a phone book application, this Entity would represent a Person in the phone book. Your View/Controller (VC) code would use this Entity, and collections of these Entities to represent entries in your phone book. You may be wondering, "OK. So, how do I go about creating/populating these Entities?". A common MVC newbie mistake is to simply start writing data access logic directly in their controller methods to create, read, update, and delete (CRUD) these. This is rarely a good idea. The CRUD responsibilities for these Entities should reside in your Model. I must stress though: the Model is not just a representation of your data. All of the CRUD duties are part of your Model layer.
Data Access Logic
Two of the simpler patterns used to handle the CRUD are Table Data Gateway and Row Data Gateway. One common practice, which is generally "not a good idea", is to simply have your Entity objects extend your TDG or RDG directly. In simple cases, this works fine, but it bloats your Entities with unnecessary code that has nothing to do with the business logic of your application.
Another pattern, Active Record, puts all of this data access logic in the Entity by design. This is very convenient, and can help immensely with rapid development. This pattern is used extensively in Ruby on Rails.
My personal pattern of choice, and the most complex, is the Data Mapper. This provides a strict separation of data access logic and Entities. This makes for lean business-logic exclusive Entities. It's common for a Data Mapper implementation to use a TDG,RDG, or even Active Record pattern to provide the data access logic for the mapper object. It's a very good idea to implement an Identity Map to be used by your Data Mapper, to reduce the number of queries you are doing to your storage medium.
Domain Model
The Domain Model is an object model of your domain that incorporates behavior and data. In our simple phone book application this would be a very boring single Person class. We might need to add more objects to our domain though, such as Employer or Address Entities. These would become part of the Domain Model.
The Domain Model is perfect for pairing with the Data Mapper pattern. Your Controllers would simply use the Mapper(s) to CRUD the Entities needed by the View. This keeps your Controllers, Views, and Entities completely agnostic to the storage medium. This also allows for differing Mappers for the same Entity. For example, you could have a Person_Db_Mapper object and a Person_Xml_Mapper object; the Person_Db_Mapper would use your local DB as a data source to build Entities, and Person_Xml_Mapper could use an XML file that someone uploaded, or that you fetched with a remote SOAP/XML-RPC call.
Service Layer
The Service Layer pattern defines an application's boundary with a layer of services that establishes a set of available operations and coordinates the application's response in each operation. I think of it as an API to my Domain Model.
When using the Service Layer pattern, you're encapsulating the data access pattern (Active Record, TDG, RDG, Data Mapper) and the Domain Model into a convenient single access point. This Service Layer is used directly by your Controllers, and if well-implemented provides a convenient place to hook in other API interfaces such as XML-RPC/SOAP.
The Service Layer is also the appropriate place to put application logic. If you're wondering what the difference between application and business logic is, I will explain.
Business logic is your domain logic, the logic and behaviors required by your Domain Model to appropriately represent the domain. Here are some business logic examples:
Every Person must have an Address
No Person can have a phone number longer than 10 digits
When deleting a Person their Address should be deleted
Application logic is the logic that doesn't fit inside your Domain. It's typically things your application requires that don't make sense to put in the business logic. Some examples:
When a Person is deleted email the system administrator
Only show a maximum of 5 Persons per page
It doesn't make sense to add the logic to send email to our Domain Model. We'd end up coupling our Domain Model to whatever mailing class we're using. Nor would we want to limit our Data Mapper to fetch only 5 records at a time. Having this logic in the Service Layer allows our potentially different APIs to have their own logic. e.g. Web may only fetch 5, but XML-RPC may fetch 100.
In closing, a Service ayer is not always needed, and can be overkill for simple cases. Application logic would typically be put directly in your Controller or, less desirably, In your Domain Model (ew).
Resources
Every serious developer should have these books in his library:
Design Patterns: Elements of Reusable Object-Oriented Software
Patterns of Enterprise Application Architecture
Domain-Driven Design: Tackling Complexity in the Heart of Software
The model is how you represent the data of the application. It is the state of the application, the data which would influence the output (edit: visual presentation) of the application, and variables that can be tweaked by the controller.
To answer your question specifically
The content of the email, the person to send the email to are the model.
The code that sends the email (and verify the email/registration in the first place) and determine the content of the email is in the controller. The controller could also generate the content of the email - perhaps you have an email template in the model, and the controller could replace placeholder with the correct values from its processing.
The view is basically "An authentication email has been sent to your account" or "Your email address is not valid". So the controller looks at the model and determine the output for the view.
Think of it like this
The model is the domain-specific representation of the data on which the application operates.
The Controller processes and responds to events (typically user actions) and may invoke changes on the model.
So, I would say you want to put the code for the e-mail in the controller.
MVC is typically meant for UI design. I think, in your case a simple Observer pattern would be ideal. Your model could notify a listener registerd with it that a user has been registered. This listener would then send out the email.
The model is the representation of your data-storage backend. This can be a database, a file-system, webservices, ...
Typically the model performs translation of the relational structures of your database to the object-oriented structure of your application.
In the example above: You would have a controller with a register action. The model holds the information the user enters during the registration process and takes care that the data is correctly saved in the data backend.
The activation email should be send as a result of a successful save operation by the controller.
Pseudo Code:
public class RegisterModel {
private String username;
private String email;
// ...
}
public class RegisterAction extends ApplicationController {
public void register(UserData data) {
// fill the model
RegisterModel model = new RegisterModel();
model.setUsername(data.getUsername());
// fill properties ...
// save the model - a DAO approach would be better
boolean result = model.save();
if(result)
sendActivationEmail(data);
}
}
More info to the MVC concept can be found here:
It should be noted that MVC is not a design pattern that fits well for every kind of application. In your case, sending the email is an operation that simply has no perfect place in the MVC pattern. If you are using a framework that forces you to use MVC, put it into the controller, as other people have said.
What is a Data Transfer Object?
In MVC are the model classes DTO, and if not what are the differences and do we need both?
A Data Transfer Object is an object that is used to encapsulate data, and send it from one subsystem of an application to another.
DTOs are most commonly used by the Services layer in an N-Tier application to transfer data between itself and the UI layer. The main benefit here is that it reduces the amount of data that needs to be sent across the wire in distributed applications. They also make great models in the MVC pattern.
Another use for DTOs can be to encapsulate parameters for method calls. This can be useful if a method takes more than four or five parameters.
When using the DTO pattern, you would also make use of DTO assemblers. The assemblers are used to create DTOs from Domain Objects, and vice versa.
The conversion from Domain Object to DTO and back again can be a costly process. If you're not creating a distributed application, you probably won't see any great benefits from the pattern, as Martin Fowler explains here.
The definition for DTO can be found on Martin Fowler's site. DTOs are used to transfer parameters to methods and as return types. A lot of people use those in the UI, but others inflate domain objects from them.
A DTO is a dumb object - it just holds properties and has getters and setters, but no other logic of any significance (other than maybe a compare() or equals() implementation).
Typically model classes in MVC (assuming .net MVC here) are DTOs, or collections/aggregates of DTOs
In general Value Objects should be Immutable. Like Integer or String objects in Java. We can use them for transferring data between software layers. If the software layers or services running in different remote nodes like in a microservices environment or in a legacy Java Enterprise App. We must make almost exact copies of two classes. This is the where we met DTOs.
|-----------| |--------------|
| SERVICE 1 |--> Credentials DTO >--------> Credentials DTO >-- | AUTH SERVICE |
|-----------| |--------------|
In legacy Java Enterprise Systems DTOs can have various EJB stuff in it.
I do not know this is a best practice or not but I personally use Value Objects in my Spring MVC/Boot Projects like this:
|------------| |------------------| |------------|
-> Form | | -> Form | | -> Entity | |
| Controller | | Service / Facade | | Repository |
<- View | | <- View | | <- Entity / Projection View | |
|------------| |------------------| |------------|
Controller layer doesn't know what are the entities are. It communicates with Form and View Value Objects. Form Objects has JSR 303 Validation annotations (for instance #NotNull) and View Value Objects have Jackson Annotations for custom serialization. (for instance #JsonIgnore)
Service layer communicates with repository layer via using Entity Objects. Entity objects have JPA/Hibernate/Spring Data annotations on it. Every layer communicates with only the lower layer. The inter-layer communication is prohibited because of circular/cyclic dependency.
User Service ----> XX CANNOT CALL XX ----> Order Service
Some ORM Frameworks have the ability of projection via using additional interfaces or classes. So repositories can return View objects directly. There for you do not need an additional transformation.
For instance this is our User entity:
#Entity
public final class User {
private String id;
private String firstname;
private String lastname;
private String phone;
private String fax;
private String address;
// Accessors ...
}
But you should return a Paginated list of users that just include id, firstname, lastname. Then you can create a View Value Object for ORM projection.
public final class UserListItemView {
private String id;
private String firstname;
private String lastname;
// Accessors ...
}
You can easily get the paginated result from repository layer. Thanks to spring you can also use just interfaces for projections.
List<UserListItemView> find(Pageable pageable);
Don't worry for other conversion operations BeanUtils.copy method works just fine.
To me the best answer to the question what is a DTO is that DTO's are simple objects that should not contain any business logic or methods implementation that would require testing.
Normally your model (using the MVC pattern) are intelligent models, and they can contain a lot of/some methods that do some different operations for that model specifically (not business logic, this should be at the controllers). However, when you transfer data (eg. calling a REST (GET/POST/whatever) endpoint from somewhere, or consuming a webservice using SOA, etc...) you do not want to transmit the big sized object with code that is not necessary for the endpoint, will consume data, and slow down the transfer.
With MVC data transfer objects are often used to map domain models to simpler objects that will ultimately get displayed by the view.
From Wikipedia:
Data transfer object (DTO), formerly known as value objects or VO, is
a design pattern used to transfer data between software application
subsystems. DTOs are often used in conjunction with data access
objects to retrieve data from a database.
All credits goes to Rick-Andreson
Production apps typically limit the data that's input and returned using a subset of the model. There are multiple reasons behind this and security is a major one. The subset of a model is usually referred to as a Data Transfer Object (DTO), input model, or view model.
A DTO may be used to:
Prevent over-posting.
Hide properties that clients are not supposed to view.
Omit some properties in order to reduce payload size.
Flatten object graphs that contain nested objects.
Flattened object graphs can be more convenient for clients.
Practical implementation of a DTO approach, by Rick-Andreson on Microsoft Web APIs best tutorials and practices using C# and ASP .Net Core 5:
The principle behind Data Transfer Object is to create new Data Objects that only include the necessary properties you need for a specific data transaction.
Benefits include:
Make data transfer more secure
Reduce transfer size if you remove all unnecessary data.
Read More: https://www.codenerd.co.za/what-is-data-transfer-objects
Some programmers use DTO to distinguish their final object data that is going to be passed through an API. So, it is basically a payload object to an endpoint. Like, you could name your contact form values object that you pass to the server as contactFormDto or contactFromPayload, then you or any other programmer know what you have in that object is final shape of the data, that is going to travel through network.
I would explain DTO to my kid as
My son, Data Transfer Object (aka DTO) **is used to encapsulate data we send from one endpoint to another.
Use DTO to define interfaces for input and output for endpoints in your system
In this context think of a system as a collection of endpoints. And endpoints can be anything between (mobile app, web app, backend API) that talk with each other.
Data transfer object (DTO) describes “an object that carries data
between processes” (Wikipedia) or an “object that is used to encapsulate data,
and send it from one subsystem of an application to another” (Stack Overflow
answer).
DefN
A DTO is a hardcoded data model. It only solves the problem of modeling a data record handled by a hardcoded production process, where all fields are known at compile-time and therefore accessed via strongly typed properties.
In contrast, a dynamic model or "property bag" solves the problem of modeling a data record when the production process is created at runtime.
The Cvar
A DTO can be modeled with fields or properties, but someone invented a very useful data container called the Cvar. It is a reference to a value. When a DTO is modeled with what I call reference properties, modules can be configured to share heap memory and thereby collaboratively work on it. This completely eliminates parameter passing and O2O communication from your code. In other words, DTOs having reference properties allow code to achieve zero coupling.
class Cvar { ... }
class Cvar<T> : Cvar
{
public T Value { get; set; }
}
class MyDTO
{
public Cvar<int> X { get; set; }
public Cvar<int> Y { get; set; }
public Cvar<string> mutableString { get; set; } // >;)
}
Source: http://www.powersemantics.com/
Dynamic DTOs are a necessary component for dynamic software. To instantiate a dynamic process, one compiler step is to bind each machine in the script to the reference properties the script defines. A dynamic DTO is built by adding the Cvars to a collection.
// a dynamic DTO
class CvarRegistry : Dictionary<string, Cvar> { }
Contentions
Note: because Wix labeled the use of DTOs for organizing parameters as an "anti-pattern", I will give an authoritative opinion.
return View(model); // MVC disagrees
My collaborative architecture replaces design patterns. Refer to my web articles.
Parameters provide immediate control of a stack frame machine. If you use continuous control and therefore do not need immediate control, your modules do not need parameters. My architecture has none. In-process configuration of machines (methods) adds complexity but also value (performance) when the parameters are value types. However, reference type parameters make the consumer cause cache misses to get the values off the heap anyway -- therefore, just configure the consumer with reference properties. Fact from mechanical engineering: reliance on parameters is a kind of preoptimization, because processing (making components) itself is waste. Refer to my W article for more information. http://www.powersemantics.com/w.html.
Fowler and company might realize the benefits of DTOs outside of distributed architecture if they had ever known any other architecture. Programmers only know distributed systems. Integrated collaborative systems (aka production aka manufacturing) are something I had to claim as my own architecture, because I am the first to write code this way.
Some consider the DTO an anemic domain model, meaning it lacks functionality, but this assumes an object must own the data it interacts with. This conceptual model then forces you to deliver the data between objects, which is the model for distributed processing. However on a manufacturing line, each step can access the end product and change it without owning or controlling it. That's the difference between distributed and integrated processing. Manufacturing separates the product from operations and logistics.
There's nothing inherently wrong with modeling processing as a bunch of useless office workers who e-mail work to one another without keeping an e-mail trail, except for all the extra work and headache it creates in handling logistics and return problems. A properly modeled distributed process attaches a document (active routing) to the product describing what operations it came from and will go to. The active routing is a copy of the process source routing, which is written before the process begins. In the event of a defect or other emergency change, the active routing is modified to include the operation steps it will be sent to. This then accounts for all the labor which went into production.