【C#重構】——模板方法在組合查詢中的實踐
阿新 • • 發佈:2018-12-22
什麼是模板方法:
模板方法模式,定義一個操作中的演算法骨架,而將一些步驟延遲到子類中。模板方法使得子類可以不改變一個演算法的結構即可衝定義該演算法的某些特定步驟。
有趣易懂的解釋:
推薦部落格:作者:Carson_Ho ,原文:模板方法易懂解析
- 背景:小成希望學炒菜:手撕包菜 & 蒜蓉炒菜心
- 衝突:兩道菜的炒菜步驟有的重複有的卻差異很大,記不住
- 解決方案:利用程式碼記錄下來
步驟1: 建立抽象模板結構(Abstract Class):炒菜的步驟
public abstract class Abstract Class { //模板方法,用來控制炒菜的流程 (炒菜的流程是一樣的-複用) //申明為final,不希望子類覆蓋這個方法,防止更改流程的執行順序 final void cookProcess(){ //第一步:倒油 this.pourOil(); //第二步:熱油 this.HeatOil(); //第三步:倒蔬菜 this.pourVegetable(); //第四步:倒調味料 this.pourSauce(); //第五步:翻炒 this.fry(); } //定義結構裡哪些方法是所有過程都是一樣的可複用的,哪些是需要子類進行實現的 //第一步:倒油是一樣的,所以直接實現 void pourOil(){ System.out.println("倒油"); } //第二步:熱油是一樣的,所以直接實現 void HeatOil(){ System.out.println("熱油"); } //第三步:倒蔬菜是不一樣的(一個下包菜,一個是下菜心) //所以宣告為抽象方法,具體由子類實現 abstract void pourVegetable(); //第四步:倒調味料是不一樣的(一個下辣椒,一個是下蒜蓉) //所以宣告為抽象方法,具體由子類實現 abstract void pourSauce(); //第五步:翻炒是一樣的,所以直接實現 void fry();{ System.out.println("炒啊炒啊炒到熟啊"); } }
步驟2: 建立具體模板(Concrete Class),即”手撕包菜“和”蒜蓉炒菜心“的具體步驟
//炒手撕包菜的類 public class ConcreteClass_BaoCai extend Abstract Class{ @Override public void pourVegetable(){ System.out.println(”下鍋的蔬菜是包菜“); } @Override public void pourSauce(){ System.out.println(”下鍋的醬料是辣椒“); } } //炒蒜蓉菜心的類 public class ConcreteClass_CaiXin extend Abstract Class{ @Override public void pourVegetable(){ System.out.println(”下鍋的蔬菜是菜心“); } @Override public void pourSauce(){ System.out.println(”下鍋的醬料是蒜蓉“); } }
步驟3: 客戶端呼叫-炒菜了
public class Template Method{
public static void main(String[] args){
//炒 - 手撕包菜
ConcreteClass_BaoCai BaoCai = new ConcreteClass_BaoCai();
BaoCai.cookProcess();
//炒 - 蒜蓉菜心
ConcreteClass_ CaiXin = new ConcreteClass_CaiXin();
CaiXin.cookProcess();
}
}
組合查詢如何體現模板方法
組合查詢在很多地方都可以用:如學生資訊查詢;學生上下機記錄查詢;學生充值資訊查詢;教師上機記錄查詢等。
組合查詢窗體的建立和初始化的內容都比較多,那就把他們共同的點抽象出來,封裝成一個類,讓如上這些子類繼承它。
例如:
第一點:父類的組合窗體抽象出來的方法:
第二點:重點看父類中的虛方法
模板方法體現在分類中的虛方法命名,在子類中實現重寫
//將查詢的內容轉換成資料庫中的列名稱
public virtual string ToName(string combo)
{
return "";
}
//獲得資料庫名稱:在子窗體中進行重寫,返回需要查詢的表名
protected virtual string Getdbtable()
{
return "";
}
//顯示資料:在子窗體中實現傳值,返回表顯示出來
protected virtual void ToDgv(enGroupFind enGroupFind)
{
}
第三點:重點看子類中的虛方法重寫
/// <summary>
/// 重寫虛方法:將查詢的內容轉換成資料庫中的列名稱
/// </summary>
/// <param name="combo"></param>
/// <returns></returns>
public override string ToName(string combo)
{
switch (combo)
{
case "卡號":
return "userID";
case "學號":
return "studentID";
case "註冊日期":
return "date";
case "與":
return "and";
case "或":
return "or";
case "非":
return "not";
//如果用到了ToName方法但是沒有輸入值則返回空
default:
return "";
}
}
/// <summary>
/// 重寫虛方法:獲得資料庫名稱
/// </summary>
/// <returns></returns>
protected override string Getdbtable()
{
return "student_info";
}
/// <summary>
/// 重寫虛方法:顯示資料
/// </summary>
/// <param name="enGroupFind"></param>
protected override void ToDgv(enGroupFind enGroupFind)
{
//傳值到外觀層
Facade.enGroupFindFacade grouFind = new Facade.enGroupFindFacade();
DataTable result = new DataTable();
result = grouFind.GroupCheck(enGroupFind);
if (result .Rows.Count == 0)
{
MessageBox.Show("沒有記錄");
}
else
{
//把查詢到的tabe result 返回到表中
dgvCollect.DataSource = result;
dgvCollect.Refresh();
}
}
具體詳細程式碼部分見:組合查詢詳細程式碼
理解還不到位,請各位指正賜教