設計模式之於程式,就像招式之於武術,招式練習的,就是常見的進攻方式,所以設計模式就是一種常見的設計招式,一開始練習時,常要思考這裡要用什麼設計模式,後來慢慢的,無意中你就是用模式來寫程式,然後就像武術大師,無招勝有招了。

先把設計物件導向程式的準則列出來,這大概就是心法了
1.獨立變動
2.對介面寫程式
3.多用合成,少用繼承

策略模式(Strategy Pattern)

這應該是我最常用到的模式了,常常我們設計一個類別家族的時候,會出現類別的某一個功能特別容易變化,例如你為公司各式各樣的報表設計了一個家族,如下:

public abstract class Report {
public string title;
public abstract void Print();
}

public class PDFReport:Report{
public override void Print(){
Console.WriteLine("PDF Format...");
}
}

public class WordReport:Report{
public override void Print(){
Console.WriteLine("Word Format...");
}
}

public class ExcelReport:Report{
public override void Print(){
Console.WriteLine("Excel Format...");
}
}

這個 Report 當中的 Print() 功能可能會因為文件格式或印表機的不同而有各式的變化,一般的解決方法像再加一個子類別如 PDFReport2,這造成因為部份改變就增加子類別的類別氾濫,或是在 Print() 內加上 If else 判斷式,這造成必需不斷修改原始類別與函式複雜化。

Strategy 的解決方法是將 Print() 內的演算法獨立出來,另外設計一個 Print 的演算法家族,並讓 Report 可以設定由那一個 Print 執行。



完整程式碼

//獨立 Print 演算法家族
public interface Print {
void print();
}

public class PDFPrint:Print{
public void print(){
Console.WriteLine("PDF Format....");
}
}

public class WordPrint:Print{
public void print(){
Console.WriteLine("Word Format....");
}
}

public class ExcelPrint:Print{
public void print(){
Console.WriteLine("Execl Format....");
}
}

// 改寫 Report 類別
public abstract class Report {
public string title;
protected Print print; // 父類別包涵 print 介面

public void SetPrint(Print aprint){ // 可以在執行時期改變 Print 實作類別
print = aprint;
}
public void Print(){
print.print(); // 交由 Print 實作類別執行
}
}

public class PDFReport:Report{
public PDFReport(){ // Report 巳不需覆寫 Print 函式,但可以在建構式指定預設的 Print 實作類別
print = new PDFPrint();
}
}

public class WordReport:Report{
public WordReport(){
print = new WordPrint();
}
}

public class ExcelReport:Report{
public ExcelReport(){
print = new ExcelPrint();
}
}

// 執行範例
PDFReport report = new PDFReport();
report.Print(); // 產生 "PDF Format.... "

report.SetPrint(new WordPrint()); // 改變預設的 Print
report.Print(); // 產生 "WordFormat.... "

之後如果有需要新的列印(Print)方式,也只要在增加 XXXPrint 物件就好了,這是 Strategy 模式的最大優點。

缺點
1.類別數量增加,程式碼變複雜
這是所有設計模式的通病,不過如果開發團體的成員都對設計模式有一定的了解,反而會使得程式容易被理解,你只要說明這裡使用的模式名稱,團體成員就可以了解一群類別的使用模式。

2.使用者必須了解 Strategy 家族的使用方法
Strategy 有一個很大的好處,就是可以在執行時期改變函式內容,但前題是使用者必須了解 Strategy 家族的使用時機。
arrow
arrow
    全站熱搜

    felixhuang 發表在 痞客邦 留言(0) 人氣()