橋接模式的補充:(下面的一段是橋接模式裡後補充的一段,橋接模式的一個小結)
什麼是交接模式?引用《大話設計模式》裡的定義:
橋接模式(Bridge):将抽象部分和他的實作部分分離,使他們都可以獨立的變化。(P229)
不知道大家有沒有看懂這個定義,至少我是沒弄懂,呵呵。再引用一段《大話設計模式》的一段解釋:(P232)
小菜:“我覺得交接模式所說的‘将抽象部分和他的實作部分分離’,還是不好了解,我的了解就是實作系統有多個角度分類,每一種分類都有可能有變化,那麼就把這種多角度分離出來讓他們獨立變化,減少他們之間的耦合。”
這個就是作者(程傑)的了解吧,這個解釋夠白話的了,不過我還想說一下我的更加白話的了解,呵呵。大家看看對不對。
我的了解就是:有兩套或者多套獨立的“多态系統”,他們可以各自獨立的變化(繼承),互不幹擾。然後選擇一套系統作為容器,在這個容器裡定義其他系統的執行個體或者借口,通過這種關系(組合/聚合)把兩套或者多套系統結合起來,配合工作。組合/聚合就好像一座橋梁一樣把這些系統結合在一起,是以就叫做橋接模式了。
就好比我的這個例子裡面,頁面基類就是一套“多态系統”,他可以派生出清單頁面基類、表單頁面基類等,把頁面基類作為容器,在其内部定義資料通路函數庫的執行個體,定義目前登入人資訊的執行個體。而資料通路函數庫還可以自行派生出SqlClient的通路類、OleDb的通路類,他們是獨立的“多态系統”互不幹擾。頁面基類如何變化不需要考慮資料通路的問題,資料通路函數庫如何變化也不用考慮有多少種頁面。這就是所謂的減少耦合吧。
=====================================================
如果我們在頁面基類裡要做一些事情,需要制定一下執行順序,而且有一些處理方法是公用的,但是有一些處理的方式又不一樣,這時候就比較适合采用模闆模式了。
比如我們在頁面基類裡override 一下OnInit(EventArgs e),在這裡制定一下執行順序,然後定義幾個虛函數(virtual)。代碼如下:
/// <summary>
/// 提取URL裡面的參數,驗證參數
/// </summary>
/// <param name="e"></param>
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
//調用函數來設定FunctionID,不同類型的頁面就可以用不同的方式來設定FunctionID了。
SetFunctionID();
//調用函數來設定ButtonID。
SetButtonID();
//調用函數來設定DataID。
SetDataID();
//調用函數來設定DepartmentID(部門ID)。
SetDepartmentID();
//調用函數來設定ForeignID(外鍵ID)。
SetForeignID();
if (!Page.IsPostBack)
{
//設定标題
SetPageTitle();
}
}
SetFunctionID()的代碼,其他代碼略。
/// <summary>
/// 設定FunctionID。
protected virtual void SetFunctionID()
//DataList.aspx、DataForm.aspx 頁面通過URL裡的參數設定。
//其他頁面自行設定
this.FunctionID = Request.QueryString["fid"];
#region 驗證子產品ID參數是否是數字。
if (!Functions.IsInt(this.FunctionID))
Response.Write("子產品參數不正确!");
Response.End();
#endregion
這樣子類就繼承了基類的執行順序,然後如果有不一樣的驗證方式,那麼就override一下就可以了。
這樣做的好處就是,把共用的東西放到父類,子類隻需要關注不一樣的地方。同時也強制了編寫規範,基類是寫好的,大家不能随便修改,如果有不同的需求,可以去改子類(override),不必去改基類,這樣也遵守了開放封閉原則。
同理,清單頁面基類也采用了模闆模式。
在自然架構裡面清單頁面裡需要使用分頁控件、查詢控件、資料顯示控件、操作按鈕組這幾個控件,那麼給這些控件設定屬性值的操作,和他們之間的關聯關系就可以放在清單頁面基類裡去做。代碼如下:
/// 在 OnInit 事件裡面設定各個自定義控件的屬性和關聯
//父類裡面驗證參數是否正确
//驗證是否有權限通路。
MyUser.CheckFunctionID(this.FunctionID);
//設定分頁控件的屬性和事件
SetQuickPagerInfo();
//設定資料表格的屬性
SetGridInfo();
//設定查詢控件的屬性
SetFindControlInfo();
//設定操作按鈕的屬性
SetButtonBarInfo();
雖然大多數清單頁面都可以這麼設定,但是也不排除特殊需求,如果又不一樣的需求的話,那麼就可以在子類裡面通過override的方式來實作自己的特殊需求。
還是那句話,把共用的放在基類裡面,子類隻關心不同點即可。
模闆模式的定義:
還是引用《大話設計模式》裡的定義。
模闆方法模式:定義一個操作中的算法的骨架,而将一些步驟延遲到子類中。模版方法可以使得子類可以不修改一個算法的結構既可以重定義該算法的某些特定步驟。【P96】
當然我這裡說的隻是模闆模式的一種形式的應用,除了這種形式的用法外還有很多種形式的用法。
=============================================
白天不能上網,被屏蔽了,是以白天就不能及時回複了,晚上在回複。