在ASP.NET中实现Model-View-Controller模式(2)_[Asp.Net教程]
					模型-视图-控制器分离的重构 
 为了解决上面所遗留的问题,你必须将模型与控制器角色分离。 
 视图的实现代码与前部分相同。 
 模型 
 下面的代码例子使模型角色仅仅依赖于数据库,而不包含任何与视图相依赖的代码。 
using System; 
using System.Collections; 
using System.Data; 
using System.Data.SqlClient; 
public class DatabaseGateway 
{ 
public static DataSet GetRecordings() 
{ 
String selectCmd = "select * from Recording"; 
SqlConnection myConnection = 
new SqlConnection( 
"server=(local);database=recordings;Trusted_Connection=yes"); 
SqlDataAdapter myCommand = new SqlDataAdapter(selectCmd, myConnection); 
DataSet ds = new DataSet(); 
myCommand.Fill(ds, "Recording"); 
return ds; 
} 
public static DataSet GetTracks(string recordingId) 
{ 
String selectCmd = 
String.Format( 
"select * from Track where recordingId = {0} order by id", 
recordingId); 
SqlConnection myConnection = 
new SqlConnection( 
"server=(local);database=recordings;Trusted_Connection=yes"); 
SqlDataAdapter myCommand = new SqlDataAdapter(selectCmd, myConnection); 
DataSet ds = new DataSet(); 
myCommand.Fill(ds, "Track"); 
return ds; 
} 
 现在的代码只依赖于数据库,这个类是一个优秀的数据库的通道,它持有访问表或视图的所用的SQL语句,其它的代码调用一些方法来完成与数据库的交互。 
 控制器 
 这种重构方式利用代码隐藏机制,在负责数据访问的模型部分相对独立的情况下,由控制器负责事件与方法的控制工作。模型的任务很明确的,它仅返回一个DataSet对象。这种实现方式就像视图代码一样,不依赖于数据是如何从数据库中返回的。 
using System; 
using System.Data; 
using System.Collections; 
using System.Web.UI.WebControls; 
public class Solution : System.Web.UI.Page 
{ 
protected System.Web.UI.WebControls.Button submit; 
protected System.Web.UI.WebControls.DataGrid MyDataGrid; 
protected System.Web.UI.WebControls.DropDownList recordingSelect; 
private void Page_Load(object sender, System.EventArgs e) 
{ 
if(!IsPostBack) 
{ 
DataSet ds = DatabaseGateway.GetRecordings(); 
recordingSelect.DataSource = ds; 
recordingSelect.DataTextField = "title"; 
recordingSelect.DataValueField = "id"; 
recordingSelect.DataBind(); 
} 
} 
void SubmitBtn_Click(Object sender, EventArgs e) 
{ 
DataSet ds = 
DatabaseGateway.GetTracks( 
(string)recordingSelect.SelectedItem.Value); 
MyDataGrid.DataSource = ds; 
MyDataGrid.DataBind(); 
} 
#region Web Form Designer generated code 
override protected void OnInit(EventArgs e) 
{ 
// 
// CODEGEN: This call is required by the ASP.NET Web Form Designer. 
// 
InitializeComponent(); 
base.OnInit(e); 
} 
///  
/// Required method for Designer support - do not modify 
/// the contents of this method with the code editor. 
///  
private void InitializeComponent() 
{ 
this.submit.Click += new System.EventHandler(this.SubmitBtn_Click); 
this.Load += new System.EventHandler(this.Page_Load); 
} 
#endregion 
} 
 测试 
 将模型部分从ASP.NET环境中分离出来能够使模型部分更容易的被测试。在ASP.NET环境中进行测试的话,你必须同时测试很多方面,如HTML代码是否正确,而读取HTML代码的工作是非常烦闷的。将模型部分分离出来,使你能够对模型部分做单独的单元测试。下面是NUnit (http://nunit.org)对模型部分进行单元测试的例子。 
using System; 
using NUnit.Framework; 
using System.Collections; 
using System.Data; 
using System.Data.SqlClient; 
[TestFixture] 
public class GatewayFixture 
{ 
[Test] 
public void Tracks1234Query() 
{ 
DataSet ds = DatabaseGateway.GetTracks("1234"); 
Assertion.AssertEquals(10, ds.Tables["Track"].Rows.Count); 
} 
[Test] 
public void Tracks2345Query() 
{ 
DataSet ds = DatabaseGateway.GetTracks("2345"); 
Assertion.AssertEquals(3, ds.Tables["Track"].Rows.Count); 
} 
[Test] 
public void Recordings() 
{ 
DataSet ds = DatabaseGateway.GetRecordings(); 
Assertion.AssertEquals(4, ds.Tables["Recording"].Rows.Count); 
DataTable recording = ds.Tables["Recording"]; 
Assertion.AssertEquals(4, recording.Rows.Count); 
DataRow firstRow = recording.Rows[0]; 
string title = (string)firstRow["title"]; 
Assertion.AssertEquals("Up", title.Trim()); 
} 
} 
 结论: 
 在ASP.NET中实现MVC模式有如下优缺点: 
 优势: 
 能够减少依赖。 程序员可以在一个ASP.NET页面中实现所有的代码。单页的实现方式,对于一些小型的且生存周期不长的程序是适用的。但如果想在不断增加的页面间共享代码的话,将代码的不同部分进行分离是非常有效果的。 
 能够减少代码的复制。 DatabaseGateway 类中的GetRecordings 和 GetTracks方法能够直接被其它的页面使用,减少了必须将方法的代码拷贝到不同页面的情况。 
 能够把不同人员的责任分开。修改页面的外观与修改数据访问的代码所用的技术是不同的,将模型与视图分开能够使负责不同工作的专家协同的工作。 
 使性能优化的成为可能 按将系统不同的职责分成不同的类,使性能的优化成为可能。前面的例子中,由于每次请求页面的时都要从数据库中读取数据。因此可在某种情况下将数据缓存,从而提高整个程序的性能。如果不将代码进行分离的话是无法做到的这点的。 
 易测试性 将模型与视图相分离使在ASP.NET环境外进行单元测试成为可能。 
 缺点: 
 增加了代码的数量及复杂度。这个例子在早期单页的实现方式的基础上增加了新的文件和代码,在无形中增加了维护的开销。一旦修改系统的话,会修改所有三种角色的代码。在一些情况下,一个文件中的修改比一些文件中修改要方便。所以在考虑是否使用MVC模式时。这种额外的开销一定要被计算在内,对一些小的程序来说,这种开销是不值得的。
来源:
助跑学院