close

image

image

1. Line5~8:宣告四種委派定義(加、減、乘、除)

2. Line9~12: 四個委派物件(加、減、乘、除)

3. Line16~19: 在MultiplyUC()創建子階段就初始化四個物件,以匿名函式實體化之。

4. Line 29: 判斷運算子的選擇

5. Line32~41:呼叫四種委派物件(運算子)

   1: namespace DelegateDemo
   2: {
   3:     public partial class MultiplyUC : UserControl
   4:     {
   5:         public delegate double Multiply(double x, double y);
   6:         public delegate double Divide(double x, double y);
   7:         public delegate double Add(double x, double y);
   8:         public delegate double Sub(double x, double y);
   9:         Add addOP;
  10:         Sub subOP;
  11:         Multiply mulOP;
  12:         Divide divOP;
  13:         public MultiplyUC()
  14:         {
  15:             InitializeComponent();
  16:             addOP = delegate (double x, double y) { return x + y; };
  17:             subOP = delegate (double x, double y) { return x - y; };
  18:             mulOP = delegate (double x, double y) { return x * y; };
  19:             divOP = delegate (double x, double y) { return x / y; };
  20:         }
  21:  
  22:         private void calcBtn_Click(object sender, EventArgs e)
  23:         {
  24:             if (opCBox.SelectedIndex < 0) MessageBox.Show("Please select an operator at least.");
  25:             double x, y, z;
  26:             double.TryParse(XTBox.Text, out x);
  27:             double.TryParse(YTBox.Text, out y);
  28:  
  29:             switch (opCBox.SelectedIndex)
  30:             {
  31:                 case 0:
  32:                     z = addOP(x, y);
  33:                     break;
  34:                 case 1:
  35:                     z = subOP(x, y);
  36:                     break;
  37:                 case 2:
  38:                     z = mulOP(x, y);
  39:                     break;
  40:                 case 3:
  41:                     z = divOP(x, y);
  42:                     break;
  43:                 default:
  44:                     z = 0;
  45:                     break;
  46:             }
  47:             resultLbl.Text = z.ToString();
  48:         }
  49:     }
  50: }

直接拉四份自製User Control物件MultiplyUC至Form1

image

image

執行結果

image

==========================================================

新增Operations.cs

1. Line 1:定義委派dOperation

2. Operations運算類別,包含兩個私有_numberA 和 _numberB,以及可以再衍生類別實體化的委派op

3. 虛擬函式Calculate(),執行委派op(NumberA, NumberB)並將結果傳回

   1: public delegate double dOperation(double a, double b);
   2:    public class Operations
   3:    {
   4:        private double _numberA = 0;
   5:        private double _numberB = 0;
   6:        protected dOperation op;
   7:        public double NumberA { get { return _numberA; }set { _numberA = value; } }
   8:        public double NumberB { get { return _numberB; } set { _numberB = value; } }
   9:  
  10:        public virtual double Calculate()
  11:        {
  12:            double result = 0;
  13:            result = op(NumberA, NumberB);
  14:            return result;
  15:        } 
  16:    }

接下來定義四個類別(加、減、乘、除),都是繼承自Operations

image

以加法為例

1. 定義加法Add方法

2. Line 4~9:重新覆寫父類別虛擬方法,首先實體化父類別中op委派,指向Add方法

3. Line 7: 執行父類別 base.Calculate(),相當於執行Add(a, b);

   1: class OperationAdd:Operations
   2:    {
   3:        private double Add(double a, double b) { return a + b; }
   4:        public override double Calculate()
   5:        {
   6:            op = new dOperation(Add);
   7:            return base.Calculate();
   8:        }
   9:    }

其他四則運算相似,先定義各自方法,在實體化父類別op委派,最後呼叫父類別Calculate進行運算。

   1: class OperationSub:Operations
   2:    {
   3:        private double Subtract(double a, double b) { return a - b; }
   4:        public override double Calculate()
   5:        {
   6:            op = new dOperation(Subtract);
   7:            return base.Calculate();
   8:        }
   9:    }
  10:    class OperationMul : Operations
  11:    {
  12:        private double Multiply(double a, double b) { return a * b; }
  13:        public override double Calculate()
  14:        {
  15:            op = new dOperation(Multiply);
  16:            return base.Calculate();
  17:        }
  18:    }
  19:    class OperationDiv : Operations
  20:    {
  21:        private double Divide(double a, double b) { return a / b; }
  22:        public override double Calculate()
  23:        {
  24:            if (NumberB == 0)
  25:            {
  26:                throw new Exception("除數不可以為零");
  27:            }
  28:            op = new dOperation(Divide);
  29:            return base.Calculate();
  30:        }
  31:    }

簡單工廠模式

1. Line 3: 靜態函式CreateOperations根據輸入字串(運算子)決定產生何種實體

2. Line9, 12, 15和18: 利用多型(Polymorphism)觀念,OperationAdd()、OperationSub()、OperationMul、或是OperationDiv,皆可以存回父類別Operations物件op

3. 使用 class 的靜態方法,依不同條件,取得不同物件,並用取得的物件,做類似的事情。缺點是要新增不同條件時,須修改到類別的靜態方法

4. 第3點簡單工廠模式(Simple Factory Pattern)的缺點,可以透過工廠方法模式(Factory Method Pattern)改善

   1: public class OperationsFactory
   2:    {
   3:        public static Operations CreateOperations(string operation)
   4:        {
   5:            Operations op = null;
   6:            switch(operation)
   7:            {
   8:                case "+":
   9:                    op = new OperationAdd();
  10:                    break;
  11:                case "-":
  12:                    op = new OperationSub();
  13:                    break;
  14:                case "*":
  15:                    op = new OperationMul();
  16:                    break;
  17:                case "/":
  18:                    op = new OperationDiv();
  19:                    break;
  20:            }
  21:            return op;
  22:        }
  23:    }

 

 

 

參考資料

1. 設計模式:簡單工廠模式 (Simple Factory Pattern)

2. 設計模式:工廠方法模式 (Factory Method Pattern)

arrow
arrow
    全站熱搜
    創作者介紹
    創作者 me1237guy 的頭像
    me1237guy

    天天向上

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