Delegate Event
上次的目標:
實務上遇到需要計算每家廠商的交易手續費,但是每家廠商計算手續費的方法不同,所以利用Delegate event去指定各家廠商的交易手續費算法(Method)。
實務上遇到需要計算每家廠商的交易手續費,但是每家廠商計算手續費的方法不同,所以利用Delegate event去指定各家廠商的交易手續費算法(Method)。
這次的目標:
每家廠商下面有多家特店,廠商的手續費是以這些特店的交易筆數(或金額)來計算手續費。
當特店的交易筆數(或金額)有異動時,必須重新計算手續費。
延續上次的專案內容..
一、 以Windows Form專案來作範例
2. Merchant\IMerchant.cs … 廠商Interface
Merchant\CMerchant.cs ... 廠商Class
Store\IStore.cs ... 特店Interface
Store\CStore.cs ... 特店Class
CalFeeMethod.cs ... 手續費計算方法
Form1.cs
Merchant\CMerchant.cs ... 廠商Class
Store\IStore.cs ... 特店Interface
Store\CStore.cs ... 特店Class
CalFeeMethod.cs ... 手續費計算方法
Form1.cs
二、 這次我們先來看看特店的部分
IStore.cs
IStore.cs
1. 程式碼
public interface IStore
{
//對應廠商
CMerchant Merchant { get; set; }
//特店代號
String Store_No { get; set; }
//交易筆數
double Trans_Cnt { get; set; }
//交易金額
double Trans_Amt { get; set; }
}
2. 比較特別的地方是加入一個CMerchant物件,可以指定某家特店屬於哪家廠商。
三、 CStore.cs
1. 因為要作到「當特店的交易筆數(或金額)有異動時,必須重新計算手續費」這些事情,所以在CStore.cs我們在set Trans_Cnt/ Trans_Amt 時,必須多作一些判斷。
2. 程式碼
public class CStore
{
CMerchant cMerchant; //對應特約機構
String sStore_No; //特店代號
double sTrans_Cnt=0; //交易筆數
double sTrans_Amt=0; //交易金額
/* 建構子 */
public CStore(String s_no)
{
sStore_No = s_no;
}
/* Merchant */
public CMerchant Merchant
{
get
{
return cMerchant;
}
set
{
cMerchant = value;
}
}
/* Store_No */
public String Store_No
{
get
{
return sStore_No;
}
set
{
sStore_No=value;
}
}
/* Trans_Cnt */
public double Trans_Cnt
{
get
{
return sTrans_Cnt;
}
set
{
/*******************************************
* 當符合以下情況時,重新統計手續費...
* 1. 筆數改變
* 2. 原筆數不為0 (表示非第一次設定筆數)
* 3. 已指定特約機構 (才知道手續費算法)
*******************************************/
if (sTrans_Cnt != value && sTrans_Cnt != 0 && cMerchant != null) //筆數改變時
{
sTrans_Cnt = value;
cMerchant.Print_Fee();
}
else sTrans_Cnt=value;
}
}
/* Trans_Amt */
public double Trans_Amt
{
get
{
return sTrans_Amt;
}
set
{
/*******************************************
* 當符合以下情況時,重新統計手續費...
* 1. 金額改變
* 2. 原金額不為0 (表示非第一次設定金額)
* 3. 已指定特約機構 (才知道手續費算法)
*******************************************/
if (sTrans_Amt != value && sTrans_Amt !=0 && cMerchant != null) //金額改變時
{
sTrans_Amt = value;
cMerchant.Print_Fee();
}
else sTrans_Amt = value;
}
}
}
3. 對,沒錯。 我們在筆數(或金額)改變時,偷偷作了一件事情,就是跟廠商說…你必須重新計算ㄧ次手續費:cMerchant.Print_Fee()
4. 那廠商怎麼知道所有它底下特店的交易筆數和金額呢? 所以Merchant介面/類別需加上一點東西。
四、 IMerchant.cs
1. 程式碼
public delegate void CalFeeHandler(double dFee_Pt, double dCnt, double dAmt);
public interface IMerchant
{
//特約機構代號
String Merchant_No {get; set; }
//底下所有特店
List<CStore> StoreList { get; set; }
//手續費
double Fee_Pt { get; set; }
//計算手續費的事件
event CalFeeHandler CalFee;
}
2. 灰底的部分就是這次新增的程式碼
→將計算手續費的delegate,傳入值分成三個:
dFee_Pt (手續費趴數),dCnt (筆數), dAmt(金額)
→新增一個List<CStore>物件,可以紀錄在這家廠商底下的所有特店(CStore)。
→將計算手續費的delegate,傳入值分成三個:
dFee_Pt (手續費趴數),dCnt (筆數), dAmt(金額)
→新增一個List<CStore>物件,可以紀錄在這家廠商底下的所有特店(CStore)。
五、 CMerchant.cs
1. 至於廠商類別的部分,也是作ㄧ些調整,故指列出調整的程式碼。
即 get/set 特店 以及 觸發計算手續費的方法 (灰字的程式碼為修改前的程式碼)。
即 get/set 特店 以及 觸發計算手續費的方法 (灰字的程式碼為修改前的程式碼)。
2. 程式碼
public class CMerchant : IMerchant
{
List<CStore> lStoreList;
/* StoreList */
public List<CStore> StoreList
{
get
{
return this.lStoreList;
}
set
{
this.lStoreList = value;
}
}
/* 觸發CalFee這個Event */
public void Print_Fee(double dNum)
{
if (CalFee == null) //未指定手續費時...
{
Console.WriteLine("未指定手續費計算事件!");
}
else //讓 CalFee 這個delegate event計算手續費
{
CalFee(dFee_Pt, dNum);
}
}
/* 觸發CalFee這個Event */
public void Print_Fee()
{
if (CalFee == null) //未指定手續費時...
{
Console.WriteLine("未指定手續費計算事件!");
}
else //讓 CalFee 這個delegate event計算手續費
{
if (StoreList != null)
{
double dCntSum = 0;
double dAmtSum = 0;
foreach (CStore myStore in StoreList)
{
dCntSum += myStore.Trans_Cnt;
dAmtSum += myStore.Trans_Amt;
}
CalFee(dFee_Pt, dCntSum, dAmtSum);
}
}
}
}
3. 程式這樣一對照,應該馬上就看出差別了。 之前我們是傳入一個交易筆數或金額讓Print_Fee() 觸發計算手續費事件(CalFee)。 這一次我們不傳入任何值,而是讓這家廠商自己去統計它底下所有特店的交易筆數和金額,再傳給delegate event(CalFee)計算手續費。
六、 CalFeeMethod.cs
1. 實作delegate event的手續費演算法沒有更動,只是配合delegate event的傳入參數變成三個:
/* 手續費 = 交易筆數*手續費趴數 */
public static void CalFee_by_TransCnt(double dFee_Pt, double dCnt, double dAmt)
/* 手續費 = 交易金額*手續費趴數/100 */
public static void CalFee_by_TransAmt(double dFee_Pt, double dCnt, double dAmt)
七、 Form1.cs
2. 就不多作解說了,流程大致如下:
a. 建立廠商(CMerchant)
b. 建立多家特店(CStore),並指定上層廠商。
c. 上層廠商加入這些特店
d. 廠商作第一次統計手續費
e. 當某廠商下任一家特店筆數/金額改變時,會重新統計該廠商的手續費。
a. 建立廠商(CMerchant)
b. 建立多家特店(CStore),並指定上層廠商。
c. 上層廠商加入這些特店
d. 廠商作第一次統計手續費
e. 當某廠商下任一家特店筆數/金額改變時,會重新統計該廠商的手續費。
3. 程式碼
private void bt_CalFee_Click(object sender, EventArgs e)
{
int MerchantCnt = lb_Mno.Items.Count;
CMerchant[] MerchantSet = new CMerchant[MerchantCnt ];
for (int index = 0; index < MerchantCnt; index++)
{
String sM_NO = lb_Mno.Items[index].ToString();
MerchantSet[index] = new CMerchant(sM_NO);
Console.WriteLine("特約機構代號:" + MerchantSet[index].Merchant_No);
List<CStore> myStores = new List<CStore>(0);
CStore storeA = new CStore("A");
storeA.Merchant = MerchantSet[index];
storeA.Trans_Cnt=10;
storeA.Trans_Amt = 100;
CStore storeB = new CStore("B");
storeB.Merchant = MerchantSet[index];
storeB.Trans_Cnt=20;
storeB.Trans_Amt = 200;
myStores.Add(storeA);
myStores.Add(storeB);
MerchantSet[index].StoreList = myStores;
switch (sM_NO)
{
case "123456":
MerchantSet[index].Fee_Pt = 0.8;
MerchantSet[index].CalFee += CalFeeMethod.CalFee_by_TransCnt;
break;
case "888888":
MerchantSet[index].Fee_Pt = 0.5;
MerchantSet[index].CalFee += CalFeeMethod.CalFee_by_TransAmt;
break;
default:
MerchantSet[index].Fee_Pt = 0;
break;
}
//列印手續費
MerchantSet[index].Print_Fee();
//改變storeA的筆數和金額
//storeA.Trans_Cnt = 30;
storeA.Trans_Amt = 100;
Console.WriteLine("");
}
}
八、 執行結果
特約機構代號:123456
手續費 = 交易筆數*手續費%=24
手續費 = 交易筆數*手續費%=40
特約機構代號:888888
手續費 = 交易金額*手續費%/100=1.5
手續費 = 交易金額*手續費%/100=1.5
特約機構代號:333333
未指定手續費計算事件!
未指定手續費計算事件!
沒有留言:
張貼留言