模型-视图-控制器分离的重构

为了解决上面所遗留的问题,你必须将模型与控制器角色分离。

视图的实现代码与前部分相同。

模型

下面的代码例子使模型角色仅仅依赖于数据库,而不包含任何与视图相依赖的代码。

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);
   }
      
   /// <summary>
   /// Required method for Designer support - do not modify
   /// the contents of this method with the code editor.
   /// </summary>
   private void InitializeComponent()
   {    
      this.submit.Click += new System.EventHandler(this.SubmitBtn_Click);
      this.Load += new System.EventHandler(this.Page_Load);

 
   }
   #endregion
}