Can a model depend on another model? Say I have a log model that other models want to access.
If it's between models that model the same part of the domain but are intended for different purposes (you mentioned logging, others would be reporting) there should be as little coupling as possible. Not to say that there should be none.
If the models model different parts of the domain coupling should be fine. If you notice your models are overlapping you should refine your context-/model- boundaries.
Related
Here's my classdiagram:
In my perspective (since each cannot function without the next one):
models compose the repositories,
repositories compose the services,
the services compose the controllers.
I think I'm wrong in my understanding of UML relationships.
What is the right way to make a class diagram in MVC?
Terminology and semantics
If classes cannot function without another one, there is a dependency. A dependency does absolutely not imply composition.
In object oriented programming, we often refer to composition, in the sense object composition. This relationship is stronger than a simple dependency. It means that each object of the class may need to knwow objects of the other class. In UML we represent this with an UML association.
In some case, the links between objects are stronger, and may have UML aggregation or UML composition semantics. But it's not because you compose objects, that there is an UML composition. Same term, different meaning (some more advice on using UML association and composition and avoiding UML aggregation: here).
In MVC, the Controller is associated with the Views and the Model, and each Views is associated with the Model as well. There is no UML composition.
Notation
You cannot compose a class with a package. Packages describe namespaces and can be nested. They can contain other UML elements. But they cannot be associated/aggregated/composed with classes.
What you are looking for seems to be a component diagram: components can be nested, and be relate to other components via interfaces. And a component can contain classes.
Content of your diagram
There seem to be a slight confusion between the DDD domain model and the MVC model. Despite the same term, the two concepts are different.
In MVC, the Model manages the knowledge, meaning the domain model and everything needed to cope with the domain model:
User, Transfer and Tax are DDD domain entities/aggregates and belong to the MVC model
Everything needed to persist this knowledge, such as UserRepository, TransferRepository, TaxRepository also belongs to the MVC model. If you'd use another persistance approache (e.g. table gateways, or active objects) you would not have repositories but other objects.
The MVC Controller processes the user input, and sends commands to views and the model. It is not a repetition of the domain objects.
Where are the views ? What is the purpose of your services ?
are they domain service, i.e. operation that involve several aggregates and do not naturally belong to any single one of them ?
are they a service layer of an application, meant to link it with the outside world?
If you persist data in a relational database and use the MVC or HMVC architectures, would a table correspond to a model? If not, what would you call that type of object? I've been hearing debates where some people call them domain objects and others don't differentiate the two.
I've been hereing debates where some people call them domain objects and others don't defferenciate the two
--> That's because this doesn't matter at all. Domain eg. from mathematics can be seen as the model because it defines the data type, range, complexity, ... = the set of possible values for your logic or function. This is mostly identical to a model. In addition to that this does not change anything to call them domain objects or model entities or whatever. The Model (in MVC world) is a concept. The way you define/implement your model is completely up to you as soon as you maintain the separation with the other layers and fits the concept.
I realize I'm conflating / confusing two different topics, but it seems like in most popular MVC frameworks that I've come across the model is a class / object-oriented (and uses some sort of ORM or ODM that I might not want to use).
My question is: If I split my files into models, views, and controllers, but my model is simply a separate file that handles business logic, validates data and handles communication with a database... but I do it in my own way that isn't object-oriented... and maybe just uses super simplistic if statements for validation... is that still considered a model? Would that still be considered MVC?
Does the model need to be a class / object-oriented or is that just a super common pattern / preference?
Thanks!!
In general "Model" refers to your Business Object Model (BOM). If you subscribe to Domain Driven Design (DDD) then your Models in a Model View Controller (MVC) architecture will be representative of your BOMs as classes or interfaces. Those BOMs may also be your classes in an Object Relational Map architecture. Since it is better for an interface to be a description of what something can do and a class as a description of what something is, you would tend to see your Models represented as classes rather than interfaces. In terms of what "logic" is allowed inside of those model classes it is really up to you and your team. For example, while it is typical to put data validation in Models you may want to abstract those rules to a separate data validation class that your model uses. There is typically not a black and white rule about where business logic goes but it is generally considered best practice for each class to have a single responsibility based on the Single Responsibility Principle as part of the SOLID model. From my experience when I have called "Model" classes things that were not the Business Object Models, like a "RepositoryModel", it can be confusing about where the code representation of the data model was. Instead I recommend using the word "Model" to be reserved for things which end users are familiar with and avoid the word "Model" for things they cannot.
Wouldn't creating ViewModels lead to redundancy? In the sense I have my domain model and I need to display the data from it on a view. So we create ViewModels, add DataAnnotations to it and display it on the View. At this point I have 2 object with almost identical data.
As others have already said, only the most trivial application can get away with passing their domain models directly to the view. Even then, it's still not a good idea for a lot of reasons.
The requirements of your view are different from the requirements for your data model. For instance, you may have a field that is required in your view, but is nullable in your vie model. If you add a `[Required]' attribute, then your model will now consider this field non-nullable.
However, my single biggest reason for never using domain models in views is for security. MVC allows you to post any value to it, and the default model binder will happily plug values you post into the model, which means if you had an IsAdmin flag, and someone posted a true value for IsAdmin, then when you saved the changes to the model, someone is now an admin.
The first rule of web security is never trust input from the user, and passing your view models directly to the view basically gives up sanitizing your data.
Yes, it is a form of redundancy. But redundancy is often required to achieve other goals. In case of Models, having this separation of view models and domain models helps in achieving a decoupled setup between your view and data-store. And it is not often that ViewModels are exact copies of Domain.
Which means, either can change without having an impact on other. I can see cases where this would be valuable - data-type changes in table need not call for deployment of the web application.
So, in summary, while there is redundancy, it is a design choice on whether the system is complex enough to benefit from this redundancy.
In 99% cases ViewModels don't lead to redundency.
The only 1% which comes to my mind is simple application with anemic domain models and pages, which shows nothing but a single model on a page. This is peculiar to content management pages.
In any other case:
1) your ViewModels will join information from multiple domain models
2) you'll have a logic specific to your domain in domain models
3) it's not a good idea to mix view-specific metainformation like DataAnnotations into your domain
Nope, using ViewModel has its own purpose. Let's think about a situation when your view has two or more Entities from the Domain Model, without a ViewModel, how are you gonna organize data? The data needed for a view sometime is not exactly like domain model, it can has
less or more information and sometime we have to pre-process data from domain before rendering view(e.g. format date time depends on client's culture).
Furthermore, ViewModel help de-couple the Web UI from the domain layer. Entities in Domain Model is not just about data representation(which is the only purpose of view model), they also have operations that mimics the business rule, you don't want expose too much domain knowledge to the UI layer who doesn't need to know.
I've read some MVC advice in the past regarding models stating that you should not reuse the same model objects for the domain and the view; but I haven't been able to find anyone willing to discuss why this is bad.
It is my opinion that creating two separate models - one for the domain, one for the view - and then mapping between them creates a lot of duplication, plus tedious mapping code (some of which might be alleviated by things like AutoMapper) that will likely be error prone.
What makes having a separate model for the two concerns worth the trouble of duplication and mapping code?
At its heart, two models is about Separation of Concerns. I want my View to work off of a single Model. I want my Domain Model to represent the conceptual model I build with the domain experts. ViewModel often has technical constraints. Domain Model is about POCO, and not being bound by technical constraints of either data shown (View) or persisted (in a DB or otherwise).
Suppose I have three entities shown on a screen. Does that mean I need to force a relationship between the three? Or just create a ViewModel component object that contains all three items. With a separate ViewModel, View concerns are separated from my domain.
why? 'cause the view shouldn't have the ability to use the model object!
Imagine you pass the project to a web designer to do the view layer. Suddenly he/she has the ability to mess around with your application's data through the model layer. That's not good.
So always only pass the data the view needs, instead of the object with methods.
J.P. Boodhoo's article Screen Bound DTOs will help you understand the design benefit.
There is also a security benefit that I have written about.
Having a presentation model simplifies your views. This is especially important because views are typically very hard to test. By having a presentation model you move a lot of work out of the view and into the domain->presentation model. Things like formatting, handling null values and flattening object graphs.
I agree that the extra mapping is a pain but I think you probably need to try both approaches in your specific context to see what works best for you.
There are even plainer concerns including the view model's ability to be specially formatted and certainly null-safe.
I guess the idea is that your domain models might extend to other implementations, not just your MVC application and that would break the seperations of concerns principle. If your View Model IS your domain model then your domain model has two reasons to change: a domain change requirement AND a view requirement change.
Seems I have duplication of rules as well.
ie. client object validation on the UI, then mapping to domain object that has to be validated.
What I tend to do however is map my set of domain objects to create a model - ie. a webpage that shows customer info, stock info, etc... my model becomes a structure that holds a Customer object and a Stock object.
CompanyPageModel
public Customer Customer{get;}
public Stock Stock {get;}
then in my mvc project ViewData.Model.Customer.Name ViewData.Model.Stock.CurrentStocks
Separation 'seems' like more work, but later, it's good to have this division of UI/Domain model...sorta like writing tests :)
I have drunk the cool-aide finally, I do like being able to mark my viewmodel with display instructions and have that all auto wired up.
What I demand now is some kind of auto generator of viewmodels from poco entities. I always set some string as an int and it takes me forever to find it. Don't even think of doing this without automapper unless you like pain.