看過前一篇博文http://www.cnblogs.com/insus/archive/2013/04/21/3029483.html 的網友,都大約知道,重構asp.net程序過程,使用了繼承的方法。說實在的,Insus.NET不太喜歡在程序中使用繼承。因為繼承在應用,由於本身的原因,很多問題無法解決,或是運行自如。就如上一篇中,每個網頁還是有很多相同的代碼,無法拿掉。接下來,Insus.NET想使用接口方式重新對上一篇的原程序重新重構一次,望網友又能從中學習到其中一些開發知識。
仔細看看App_Code目錄下的Unitcode1 ~ UnitCode4個類別,均有相似之處。Insus.NET在重構它們之前,先創建一個接口,然后去讓這四個類別來實作這個接口:
這個接口與前一篇的基類不一樣,畢竟一個是接口一個類,但有一點值得注意的是屬性中,多一個主鍵字段的屬性相關的
string UnitCode { get; set; }
在繼承中,它沒有辦法抽取出來。現在寫成接口之后,它可以了。接下來,我們分別對App_Code目錄下的UnitCode1 ~ UnitCode4類別實作剛才的好寫的接口,步驟有1,2,3
接下來,是對UnitCode1.aspx.cs ~ Unitcode4.aspx.cs的主鍵由Unit1~Unit4均改為UnitCode:
緊跟着看到的是每頁aspx的GridView的ID,DataKeyNames,以及OnRowEditing,OnRowCancelingEdit,OnRowUpdating,OnRowDeleting事件名稱不一樣,最后是綁定主鍵時,不相同,其余的均一樣。
為解讓每個網頁這些不一致的地方,改為一樣,得動一些手腳,刪除箭頭所指的數字。
每個UnitCode1~3.aspx.cs的事件中,也應該修改,參考下圖,把箭頭的數據全刪除:
全部改完之后,所有UnitCode1~4.aspx只差下圖高亮位置的差異了:
改為動態產生或是加載是。在GridView中,去掉DataKeyNames="Unit1"屬性。在顯示ItemTemple中,改為一個標簽,並為GridView添加一個事件 OnRowDataBound="GridViewUnitCode_RowDataBound"。
重構到這里,我們已經完成一半的工作量了。接下來,我們將創建一個用戶控件[UnitCodeForm.ascx]
由於四個.aspx均一樣,那隨便打開一個,把:

<table class="table"> <tr class="tableRow"> <td class="tableCell" style="width: 35%;">單位碼</td> <td class="tableCell">說明</td> <td style="width: 12%; text-align: center;" class="tableCell">操作</td> </tr> <tr> <td class="tableCell"> <asp:TextBox ID="TextBoxUnitCode" runat="server" CssClass="textbox" BackColor="#ffff6f"></asp:TextBox> <asp:RequiredFieldValidator ID="RequiredFieldValidator2" runat="server" ControlToValidate="TextBoxUnitCode" Display="none" ErrorMessage="單位碼必須填寫。" ValidationGroup="GeneralInsert"></asp:RequiredFieldValidator> </td> <td class="tableCell"> <asp:TextBox ID="TextBoxDescription" runat="server" CssClass="textbox"></asp:TextBox> </td> <td style="width: 12%;" class="tableCell"> <asp:ValidationSummary ID="ValidationSummary1" runat="server" EnableClientScript="true" ShowMessageBox="true" ShowSummary="false" ValidationGroup="GeneralInsert" /> <asp:Button ID="ButtonCreate" runat="server" OnClick="ButtonCreate_Click" Text="創建" ValidationGroup="GeneralInsert" /> </td> </tr> </table> <asp:GridView ID="GridViewUnitCode" runat="server" AutoGenerateColumns="false" ShowHeader="false" CellPadding="2" CellSpacing="0" Width="100%" BorderWidth="1px" BorderColor="#c0c0c0" BorderStyle="solid" HeaderStyle-Height="25" RowStyle-Height="25" HeaderStyle-BackColor="#efebde" OnRowEditing="GridViewUnitCode_RowEditing" OnRowCancelingEdit="GridViewUnitCode_RowCancelingEdit" OnRowUpdating="GridViewUnitCode_RowUpdating" OnRowDeleting="GridViewUnitCode_RowDeleting" OnRowDataBound="GridViewUnitCode_RowDataBound"> <Columns> <asp:TemplateField> <ItemStyle BorderStyle="solid" BorderWidth="1px" BorderColor="#c0c0c0" Width="35%" /> <ItemTemplate> <asp:Label ID="LabelUnitCode" runat="server" Text=""></asp:Label> </ItemTemplate> </asp:TemplateField> <asp:TemplateField> <ItemStyle BorderStyle="solid" BorderWidth="1px" BorderColor="#c0c0c0" /> <ItemTemplate> <%# Eval("Description") %> </ItemTemplate> <EditItemTemplate> <asp:TextBox ID="TextBoxDescription" runat="server" Text='<%# Eval("Description") %>' CssClass="textbox"></asp:TextBox> </EditItemTemplate> </asp:TemplateField> <asp:TemplateField> <ItemStyle BorderStyle="solid" BorderWidth="1px" BorderColor="#c0c0c0" Width="8%" /> <ItemTemplate> <asp:Button ID="ButtonEdit" runat="server" Text="編輯" CommandName="Edit" CausesValidation="false" /> </ItemTemplate> <EditItemTemplate> <asp:ValidationSummary ID="ValidationSummary2" runat="server" EnableClientScript="true" ShowMessageBox="true" ShowSummary="false" ValidationGroup="GrieviewUpdate" /> <asp:Button ID="ButtonUpdate" runat="server" Text="更新" CommandName="Update" ValidationGroup="GrieviewUpdate" /> <asp:Button ID="ButtonCancel" runat="server" Text="取消" CommandName="Cancel" CausesValidation="false" /> </EditItemTemplate> </asp:TemplateField> <asp:TemplateField HeaderText="刪除"> <ItemStyle BorderStyle="solid" BorderWidth="1px" BorderColor="#c0c0c0" Width="4%" /> <ItemTemplate> <asp:Button ID="ButtonDelete" runat="server" Text="刪除" CommandName="Delete" CausesValidation="false" /> <ajaxToolkit:ConfirmButtonExtender ID="ConfirmButtonExtender1" runat="server" TargetControlID="ButtonDelete" ConfirmText="確認刪除記錄?"> </ajaxToolkit:ConfirmButtonExtender> </ItemTemplate> </asp:TemplateField> </Columns> </asp:GridView>
html剪下,並帖至UnitCodeForm.ascx去,留下:
在.aspx.cs中的代碼,如下:

protected void ButtonCreate_Click(object sender, EventArgs e) { try { objUnitCode1.UnitCode = this.TextBoxUnitCode.Text.Trim(); objUnitCode1.Description = this.TextBoxDescription.Text.Trim(); objUnitCode1.CreateBy = "Insus.NET"; objUnitCode1.Insert(); Data_Binding(); InitializationControlStatus(); objInsusJsUtility.JsAlert("單位碼成功創建。"); } catch (Exception ex) { objInsusJsUtility.JsAlert(ex.Message); } this.TextBoxUnitCode.Text = string.Empty; this.TextBoxDescription.Text = string.Empty; } protected void GridViewUnitCode_RowEditing(object sender, GridViewEditEventArgs e) { GridViewUnitCode.EditIndex = e.NewEditIndex; GridViewUnitCode.EditRowStyle.BackColor = Color.FromName("#F7CE90"); Data_Binding(); } protected void GridViewUnitCode_RowCancelingEdit(object sender, GridViewCancelEditEventArgs e) { GridViewUnitCode.EditIndex = -1; Data_Binding(); } protected void GridViewUnitCode_RowUpdating(object sender, GridViewUpdateEventArgs e) { try { GridViewRow gvr = GridViewUnitCode.Rows[e.RowIndex]; objUnitCode1.UnitCode = GridViewUnitCode.DataKeys[e.RowIndex].Value.ToString(); objUnitCode1.Description = ((TextBox)gvr.FindControl("TextBoxDescription")).Text.Trim(); objUnitCode1.UpdateBy = "Insus.NET"; objUnitCode1.Update(); GridViewUnitCode.EditIndex = -1; Data_Binding(); objInsusJsUtility.JsAlert("單位碼成功更新。"); } catch (Exception ex) { objInsusJsUtility.JsAlert(ex.Message); } } protected void GridViewUnitCode_RowDeleting(object sender, GridViewDeleteEventArgs e) { try { GridViewRow gvr = GridViewUnitCode.Rows[e.RowIndex]; objUnitCode1.UnitCode = GridViewUnitCode.DataKeys[e.RowIndex].Value.ToString(); objUnitCode1.Delete(); Data_Binding(); objInsusJsUtility.JsAlert("單位碼成功刪除。"); } catch (Exception ex) { objInsusJsUtility.JsAlert(ex.Message); } } private void InitializationControlStatus() { this.TextBoxUnitCode.Text = string.Empty; this.TextBoxDescription.Text = string.Empty; } protected void GridViewUnitCode_RowDataBound(object sender, GridViewRowEventArgs e) { }
也切下粘貼至UnitCodeForm.ascx.cs中去,此時,你嘗試去行程序時,肯定會有很多錯誤,因為粘帖過去的,僅是其中一個實例。而原程序中是有四個實例。
OK,這個不是問題,因為重構一開始,我們就寫了接口,四個類別也分別實作了那個接口。
處理這個問題,我們使用多態來解決它。
到這里,還是有一個小問題,就是,在每個網打開時,我們要讓程序知道我們要處理的那一個UnitCode1 ~ UnitCode4中的那一個?
那可以從網頁傳一個參數給用戶控件即可,當用戶控件接收到此參數,就知道是誰發出的命命令了。怎樣傳,怎樣接收呢?是否有看到最原始的程序中,已經有一個接口了,對,我們就用那個接口:

using System; using System.Collections.Generic; using System.Linq; using System.Web; /// <summary> /// Summary description for ISetValable /// </summary> namespace Insus.NET { public interface ISetValable { void SetValue(object obj); } }
用戶控件UnitCodeForm.ascx.cs實作這個接口:
參考下面動畫,把每個頁面的參數傳用戶控件中去:
然后,把下面的方法寫入用戶控件中:
private void Data_Binding() { this.GridViewUnitCode.DataSource = objUnitCode1.GetAll(); this.GridViewUnitCode.DataBind(); }
把這句也寫入用戶控件中去:
InsusJsUtility objInsusJsUtility = new InsusJsUtility();
上圖16行,是宣告一個變量,將是主鍵值。19行是把從網頁傳過來的參數存儲入變量ucs中。21是使用反射和多態。22行是keyName。
接下來,我對所有.aspx.cs中的objUnitCode1均改objUnitCode。
最后一個動作,就是:
添加上面一句,為GridView動態添加主鍵。
OK,重構完畢,本次重構,應用了接口,然后可以輕易把四個網頁搬移至一個用戶控件中去。其中有應用了開發中的多態,以及反射技術。
下面是重構完畢的源程序:
http://download.cnblogs.com/insus/ASPDOTNET/Ref_Org_interface.rar