I am just starting on ASP.NET MVC trying to understand the philosophy first. I think I am pretty clear on the roles played by the controller and the view but I am a little confused on the model part. Some sources say its the domain model, some say its the data model, some say its the objects that are bound to the view.
IMHO these are very different things. So please can someone clear this up once and for all?
The model is "the domain-specific representation of the information on which the application operates". It's not just the data model, as that's a lower level than the MVC pattern thinks about, but (for example) it's the classes that encapsulate the data, and let you perform processing on them.
Scott Guthrie from MS uses this definition in his announcement:
"Models" in a MVC based application
are the components of the application
that are responsible for maintaining
state. Often this state is persisted
inside a database (for example: we
might have a Product class that is
used to represent order data from the
Products table inside SQL).
Further reading:
the MVC Wikipedia article
the MVC pattern on C2
I like to actually add an additional layer to make things clearer. Basically, the "Model" is the thing that is domain specific, and knows how to persist itself (assuming persistence is part of the domain).
IMO, the other layer I referred to I call the ViewModel ... sometimes, the "model" that gets passed to the view really has nothing to do with the domain ... it will have things like validation information, user display info, lookup list values for displaying in the view.
I think that's the disconnect you're having :-)
Your sources of advice are correct when they say it is the domain model. In many instances, it will be quite closely aligned your data model as well.
Where the domain and data models differ is that the data model is relatively static in form (not content) whereas your domain model adds the specific constraints and rules of your domain. For example, in my data model (database) I represent blood pressure as smallints (systolic and diastolic). In my domain model, I have a "blood pressure reading" object that holds values for each of the two readings and that also imposes additional restrictions on the range of acceptable values (e.g. the range for systolic is much smaller than that for smallints). It also adds qualitative judgments on these values (a BP of 150/90 is "high").
The addition of these aspects of the problem domain is what makes the domain model more than just the data model. In some domains (e.g. those that would be better rendered with a fully object-oriented data model and that map poorly on the relational model) you'll find that the two diverge quite significantly. However, all the systems I've created feature a very high degree of overlap. Indeed, I often push a fair number of domain constraints into the data model itself via stored procedures, user-defined types, etc.
You should have a look at this it a step by step tutorial.
From one of the chapters: page 26
In a model-view-controller framework the term “model” refers to the objects that represent the data of
the application, as well as the corresponding domain logic that integrates validation and business rules
with it. The model is in many ways the “heart” of an MVC-based application, and as we’ll see later
fundamentally drives the behavior of it.
Hope its useful.
For example, if you're building a web site to, say, manage operations of a nuclear plant, than the model is the model of the plant, complete with properties for current operating parameters (temperature etc.), methods to start/stop power generation, etc. Mmmm... in this case the model is a actually a projection of a real plant vs. an isolated mode but you got the idea.
Related
In our ASP.Net project we've got a view with 3 (or even more) cascaded combo-boxes,
The question is how should we design our (NHibernate-based) entities given that the relationship between the combo-boxes is relevant only for the sake of building the view, and given that the entire catesian product of the 3 entity types is around 2000 entities.
So the questions are actually:
Should we design the entities as a heirarchy even though the collections has no additional business value (thus making them an overhead for any other scenario)
Should the data be sent as flat rows? keeping the entities more "clean", but requires additional
coding on the view's side
Seperate to consequent requests (e.g only after combo A is selected, combo B's data is fetched from the server)? making the entire process maybe more efficient but at the cost of performance and perhaps caching?
Any thoughts?
First of all, you should not design your model (entities) by one intended UI. Today is it 3 dropdown, tommorow it can be autocomplete nad in a week some new fancy "wow" component, but your model should stay solid - it describes actual, business relations between entities, not your current UI. From this, i think it is quite obvious that you should use combination of 2 and 3.
I have a situation where I have Model A that has a variety of properties. I have discovered that some of the properties are similar across other models. My thought was I could create Model B and Model C and have Model A be a composite with a Model B property and a Model C property.
Just trying to determine if this is the best way to handle this situation.
It's definitely valid in certain situations. Let's say you have a Person class and a Company class, and they have the common properties streetNumber, streetName, postcode, etc. It makes sense to make a new model class called Address that both Person and Company contain. Inheritance is the completely wrong way to go in such a situation.
When properties (e.g. state) are the elements of commonality, I definately tend towards using composition rather than inheritance. When using inheritance, its perhaps best to wait until behavior is the commonality, and overrides are needed now or imminently.
What you're looking at is creating an Aggregate Root. A core paradigm of the Domain Driven Design (DDD) principals.
Certain models in your app will appear to belong "at the top" or "as root" to other objects. For example in the case of customers you might have a Contact model which then contains a collection of ContactPoints (names, addresses, etc).
Or a Post (in the case of a blog), which contains a collection of Comments, a Tite, Body and a TagSet (for tagging). Notice how the items i've highlighted as objects - these are other model types as opposed to simple types (strings, ints, etc).
The trick will come when and how you decide to 'fill' these Aggregate Root trees/graphs. Ie. How will you query just for a single TagSet? Will you go to the top and get the corresponding Post first? Maybe you just wanted to rename the tag "aspnetmvc" to "asp.net-mvc" for all Posts so you want to cut in and just get the TagSet item.
The MVC Storefront tutorial has some good examples of this pattern. Take a look if you can.
I'm not sure if this question is non-sense or not, please tell me if so. I am wondering do I create my models like one per each table in my database, or do you do one per controller? Is there something I am missing here?
From what I read the Model is suppose to be a representation of the real business objects, so would I just want to make it one big model or divide them out based on things in the app? based on real user/client perception of the data?
Thanks for your advice.
There's nothing wrong with controllers sharing models. But trying to serve every controller with the same model doesn't make sense.
Models and controllers really are't related, nor should they be. Models also aren't directly related to how data is stored in your application.
Models encapsulate data. Their design should be dictated by the data they are encapsulating. The demands of the system dictate what models you'll need and what data they must hold.
Don't try to overthink it. For a given request, determine what you need to show in your view and how it will be displayed. Determine what an appropriate model would look like for this scenario. If one already exists, use it. If not, create a new model. Save the overengineering later when you know what your needs are and can find commonalities between models.
Models can also contain other models, that's fine. Think of a model for a sales report. You would have a model for the report which would contain not only a report name, a total, but also a collection of other models which make up the report's line items.
It depends on what you mean by "Model". If by model you mean the business rule layer of your application, then there is no relationship in terms of numbers. One model of that type is used for any amount of views you need to build.
Personally, however, I would not bind any view to any model, but create an intermediary layer called a ViewModel that essentially taylors the data from your model to fit a particular view. In that case, the relationship is one-to-one. This is essentially how Presenter patterns work. Every view is strongly typed to it's own ViewModel that is populated from the Model layer.
Models do not necessarily have a literal coorespondence with the database either. How you store data your model is different from how your "Model" uses that data.
I have an ASP.NET MVC site and I am trying to figure out separation of controller and model (repository) and HTML helper functionality.
The goal is to query a database table of photo albums information and display it grouped by year.
The steps are:
Query database and return datatable of the database information.
Convert Datatable to AlbumCollection (List)
Bucket albums by year into ALbumDictionary
Render each year in a seperate HTML table.
Given this request, I could see:
1,2,3 all in the model and the controller simply binds the View to the AlbumDictionary model
or
1,2 in the model and bind to the AlbumCollection and 3 in a HTML ViewHelper
or
1,2 in the model 3 in the controller and bind to the Albumdictionary
Thoughts?
Doing every conversion in the first loop would have the best performance but I am not sure it is the best separation of concerns.
In particular to the above question, generic feedback would be interesting: when does separation of concerns overrule performance or vise versa?
Having been a user of some truly horrendous software that I'm sure looked good from an object-oriented perspective to the designers and was even possibly easy to maintain, I want to point out that the users will come down on the side of performance almost every time.
If the performance difference is negligible, follow the separation of concerns, if it is not, do what it takes to get the best performance. We need to stop worrying as much about the extra few minutes to possibly maintain (maybe touching that code once a year once it's in prod) and more about slowness for all the users every day issue. We like to say that development time is so expensive that we need to minimize it, but the truth is that development time is often far cheaper than the amount of time we are asking our users to waste daily.
I would try to keep the Model clear of anything that has to do with rendering.
I see the grouping by year pretty close to rendering. Thats why I would not put it into Model and also not into the Controller. A common aproach is to have a Model of Poco and DAL/BLL and anonther Model called ViewModel (the Model used by the strongly typed View). This is a good place to prepare the objects for rendering.
In ViewModel I would use Linq to group the albums by years. This will hopefully be fast enough.
I would do the bucketing in the controller only if either:
the bucketing occurs just once and I can do that with one or two simple statements;
It occurs more than once but I can do that with just a AlbumDictionary.BucketByYear() statement.
Otherwise I'd use models to do that.
I've been trying to wrap my mind around DDD and how it can relate to MVC, but I'm having trouble with regards to entity identification.
In particular, I'm trying to maintain strict separation between my presentation, domain, and data models. My hangup here is in how I preserve entity identification across these boundaries. To clarify, I'm using separate classes to represent the same entity in different contexts - for example, I have a 'ShipmentRequest' domain class, several 'ShipmentRequestView' presentation classes (depending on the properties required by a particular view), and a 'shipment_request' database table (my data model).
I feel like using an 'ID' property (like ShipmentRequestId) would be a violation of the separation I'm trying to achieve, since this ID property is a database concern, and not a domain concern; and I don't want to pass the same object between layers, as this would mean passing unneeded data into my presentation layer.
How do I preserve this separation, and yet track identity between these layers?
Without the Id field in your entity you cannot map it to a database row. Therefore this id field even though it has nothing to do with your entities must leak into your domain model.
I feel it is most often overkill to use a presentation model, especially if what your are trying to achieve is hide some properties.
I think separation of concerns is mostly driven by the bounded context. For example, your Person, PersonView and Person table all seem the relate to a transaction processing context. In such a context I would make not even have a PersonView and the person table would be abstracted away.
On the other hand if you are in a reporting context, a PersonView would be more useful.
I think that the context is much more important than any layering scheme.
As for the lack of a natural key in your person entity, it could mean that Person is not really an entity. For exemple, in any real life application, there is always a number associated with the person: an employee has a employee number, a client as an account number, etc. This business id is definitely part of the domain.
I think having an "ID" field on entities is a concession a lot (most?) people end up making, and I wouldn't feel guilty for doing so.
As you say, even when you're not dealing with the database, you still need some notion of identity. You can try to come up with some kind of "natural" identity for each entity (a field like name, or a combination of several fields), but this isn't always possible. Even when it is, having an ID field often acts as a handy shortform for saying "the entity whose name is X, and whose date of birth is Y, and whose SSN is Z".
In the end, while arguably less "pure", having an ID field will likely simplify things a great deal.
Shipment Request is definitely a better example!
How will the users find a shipment request?
Depending on the answer you might need an id that users might remember, for example 20091012-A.
Can a shipment request id ever change?
If no, use the db key for identity.
Will you need to transfer shipment requests from one system to another?
If yes, do not use the db key for identity.
Whatever key you use you will need to make it available in the presentation model so that you can build links to actions on a particular shipment request.