[转]An Architectural View of the ASP.NET MVC Framework
来源:http://dotnetslackers.com/articles/aspnet/AnArchitecturalViewOfTheASPNETMVCFramework.aspx#363
Published: 21 Nov 2007
By: Dino Esposito
Dino Esposito introduces the ASP.NET MVC framework.
Introduction
At DevConnections Fall and TechEd Europe, Microsoft recently unveiled the ASP.NET MVC Framework. MVC stands for Model-View-Controller and is one of the most popular design patterns for decoupling data access and business logic from data presentation and user interaction. At the time of this writing, the framework is not available yet, not even as a CTP. However, the first CTP is expected to ship in just a few weeks.
In any case, the ASP.NET MVC Framework is definitely worth a look since it addresses aspects of programming that are extremely important for developers and their productivity such as code reusability, testing, and separation of presentation and business logic concerns. At the same time, an early look at the MVC Framework may generate good feedback to Microsoft and help them to deliver a better and richer product in full accordance with the community expectations and needs.
Motivating the Hype on MVC
Most applications, and especially Web applications, have their presentation layer mixed up with some business logic and data access code. As an example, think of a classic ASP.NET page. You define the user interface by composing and configuring server controls until you obtain the desired markup. Next, you use a code-behind class to add some handlers for the various events fired by controls and provide any required glue code. In such pages, more often than not, data access code is interspersed with presentation logic. In ASP.NET 2.0, the introduction of data source controls certainly didn't make this mixture more unlikely. Some data source controls, such as the SqlDataSource control, are a sinful temptation for developers as they see in it the way to go down to SQL queries and stored procedures - the raw data - very quickly. Without beating the bush around, such ASP.NET pages whose code-behind classes contain a mixture of presentation, business and data access code, are quite difficult to maintain. And they are definitely challenging to test appropriately.
User interface facilities (i.e., wizards and tools in Visual Studio) tend to encourage developers to put in the presentation layer more than it should. The presentation layer acts as a catch-all for logic that reasonably belongs to other layers. At the end of the day, you can still have the application working and perform well. Behind the scene, though, you get a too high level of coupling and subsequently high costs of maintenance. What if, in fact, at some point you need to add a new feature or re-implement an existing one? Not having a well designed structure of classes and lacking a clean separation of presentation, business and data layers, most that you can do is cutting and pasting code and run pages over and over again to test results against expectations.
There's not much of reusability too, but quite the reverse I'd say. Code duplication is not unlikely and the need of changing the view for the same data may often result in serious trouble.
Sure, there are architectural design patterns to give you guidance on the best way to design Web applications with cleanly separated layers. However, these patterns require a lot of coding, sometimes repetitive code, which doesn't always sit well with the rush of delivering applications that just work. While the startup costs of implementing recognized patterns manually will certainly pay you off in the context of complex enterprise applications, it seems to be an unnecessary complication in simpler, but still realistic, scenarios.
The classic code-behind model of ASP.NET provides the tools for building great and well-designed applications, but it leaves most of it up to the individual developer or team. As a result, too many applications out there work well, but are not well designed. Over the years, this fact raised the need of a radically different approach to Web programming. The MVC pattern was soon identified as an excellent approach to Web development. MVC ensures a clean separation between the data model and the user interface in such a way that changes to the user interface don't affect data handling. At the same time, the data model and related access code can be refactored without the need of changing the user interface accordingly.
Where Did I See This Already?
Tools like Castle MonoRail have been created to simplify Web development by leveraging the MVC pattern. Where's the difference between MonoRail and ASP.NET? It mostly lies in an extremely simplified form of the code that backs a page up. It's like breaking the code you have in, and reference from, the code-behind class into distinct elements. The controller handles application flow; the model represents the data; the view takes care of presentation. The underlying engine automates some tasks for you (i.e., binding data to form elements) and exposes just plugs for you to connect and customize the engine. As a result, you write less code and have highly specialized components that are easier to test and maintain.
At the same time, MonoRail is not necessarily better than Web Forms and may not be the right choice for just everybody. Because it propounds a different paradigm, it may not be the ideal environment for those who have strong ASP.NET skills and find it difficult (or just not affordable) to convert large applications.
By the way, regardless of the Mono prefix in the name there's no necessary connection between this project and the Mono project aimed at providing the code to run .NET applications on multiple platforms.
Comparing the MVC Framework to Classic ASP.NET
The ASP.NET MVC Framework is essentially the Microsoft's attempt to create an ASP.NET programming environment centered around the MVC pattern. For the time being (nobody can reasonably foresee future evolutions), the MVC Framework should be considered an alternative to Web Forms. To some extent, the MVC Framework and Web Forms have in common more or less what cars and motorcycles share. Both can take you somewhere else, but with different speed, comfort, sense of freedom, size of the trunk.
The MVC Framework doesn't support classic postbacks and viewstate and doesn't consider any URL as the endpoint to a physical server file to parse and compile to a class. In ASP.NET, you have a 1:1 correspondence between a URL and a resource. The only exception to this rule is when you use completely custom HTTP handlers bound to a particular path.
In the MVC Framework, a URL is seen as the mean to address a logical server resource, but not necessarily an ASPX file to parse. So the URLs employed by the pages of an MVC Framework application have a custom format that the application itself mandates. In the end, the MVC Framework employs a centralized HTTP handler that recognizes an application-specific syntax for links. In addition, each addressable resource exposes a well-known set of operations and a uniform interface for executing operations.
Have you ever heard about Representational State Transfer, or REST for short?
Well, REST is an architectural pattern that defines how network resources should be defined and addressed in order to gain shorter response times, clear separation of concerns between the front-end and back-end of a networked system. REST is based on three following principles:
- An application expresses its state and implements its functionality by acting on logical resources
- Each resource is addressed using a specific URL syntax
- All addressable resources feature a contracted set of operations
As you can see, the MVC Framework fulfills it entirely.
So here's an alternate way of looking at the MVC Framework. It is an ASP.NET framework that performs data exchange by using a REST model versus the postback model of classic ASP.NET. Each page is split into two distinct components -controller and view - that operate over the same model of data. This is opposed to the classic code-behind model where no barrier is set that forces you to think in terms of separation of concerns and controllers and views. However, by keeping the code-behind class as thin as possible, and designing the business layer appropriately, a good developer could achieve separation of concerns even without adopting MVC and its overhead. MVC, however, is a model superior to a properly-done code-behind for its inherent support for test-driven development.
The figure below summarizes my perspective of classic ASP.NET and the MVC Framework.
Figure 1: Contrasting ASP.NET and the MVC Framework
While MVC is definitely a key part of the framework, I wouldn't consider it is the most compelling part. REST is a possible alternative to the postback model, whereas MVC is an alternative to code-behind.
Explaining the MVC Framework to ASP.NET Developers
Awaiting for the first binaries to ship in just a few weeks, you can get some demo code for your home perusal from the Scott Hanselman's blog. The Scott Guthrie's blog offers a few insightful posts already and I suggest you monitor it for further news and examples. Here's a list of other interesting posts you might want to read:
- The REST-like Aspect of MVC Framework
- ASP.NET MVC Framework: An early look
- RSS Feed with the new ASP.NET MVC Framework
- MVC, REST, and the Alternative ASP.NET Framework
- ASP.NET MVC framework - ready or not
I wonder what's the quickest and most effective way to explain the MVC Framework to seasoned ASP.NET developers. It's like having a central HTTP handler that captures all requests to resources identified with a new extension. This HTTP handler analyzes the syntax of the URL and maps it to a special server component known as the controller. The controller supports a number of predefined actions. The requested action is somehow codified in the URL according to an application-specific syntax. The central HTTP handler invokes the action on the controller and the controller will process the request up to generating the response in whatever response format you need. The response is generated through a view component.
What here I called the "central HTTP handler" plays the same role that was of the System.Web.UI.Page class in classic ASP.NET. The Page is the handler responsible for any .aspx
request and generates the markup using the code-behind class and serves it back using postbacks. In the MVC Framework, this pattern - hard-coded in the ASP.NET runtime and not subject to change until the whole ASP.NET platform is rewritten - is simply implemented using an alternative HTTP handler and an alternative model based on REST and MVC.
Now the one-million question that everybody should try to answer. When and why do I need REST and MVC? Stay tuned, time will tell.