摘要:NHibernate系列之五_策略模式與繼承Table Per Class
最近看到一篇文章 http://lostechies.com/jimmybogard/2008/08/27/strategies-and-discriminators-in-nhibernate/,討論了如何應用Table Per Class來對應strategy模式的使用。我覺得以後可能用的到,就此記錄下來。
首先我有以下的類別結構。Order的SumAmount統計了所有OrderDetail的SellPrice與Quantity的乘積,依據使用不同 的付款方式,需支付不同的Fee。所以Order會向FeeStragety取得應支付的費用,然後存在FeeAmount裏面
Order類別內容如下,在ReCalculate時,向FeeStrategy取得額外支出的費用。
public class Order
{
public virtual FeeStrategy Strategy { get; set; }
........
public virtual void ReCalculate()
{
decimal total = 0;
foreach (OrderDetail orderDetail in OrderDetails)
{
total += (orderDetail.SellPrice * orderDetail.Quantity);
}
SumAmount = total;
this.FeeAmount = Strategy.GetFee(this);
}
}
Order.hbm.xml的配置如下,使用多對一,關聯到FeeStrategy的ID
.....
FeeStrategy類別是個父類別,並提供一個Creation的靜態Method,來產生子類別
public class FeeStrategy
{
public virtual int No { get; set; }
public virtual decimal GetFee(Order order)
{
return 0;
}
public static CreditCardFee newCreditCardFee()
{
CreditCardFee creditCardFee = new CreditCardFee();
creditCardFee.No = 1;
return creditCardFee;
}
}
CreditCardFee子類別如下
public class CreditCardFee : FeeStrategy
{
public virtual decimal FeePercent { get; set; }
public override decimal GetFee(Order order)
{
return order.SumAmount * FeePercent;
}
}
FeeStrategy.hbm.xml的設定,把discriminator的欄位指定給No,所以Order可以透過關聯欄位FeeStategyNo,取得對應的子類別。
所以當我存入一筆Order
Order order = new Order();
order.ShoppingDate = new DateTime(2012, 1, 14);
ProductDesc productDesc = new ProductDesc();
productDesc.Name = "鉛筆";
productDesc.Price = 8;//實際價格
OrderDetail orderDetail = new OrderDetail();
orderDetail.Quantity = 20;
orderDetail.SellPrice = 10;//售出時價格,所以總和是200
orderDetail.SellProductDesc = productDesc;
//使用信用卡支付,但要付總價1成的費用
CreditCardFee creditCardFee = FeeStrategy.newCreditCardFee();
creditCardFee.FeePercent = 0.1m;
order.Strategy = creditCardFee;
order.AddDetail(orderDetail);
預期到的結果如下
Order order = session.Get(1);
order.ReCalculate();
Assert.IsInstanceOf(typeof(CreditCardFee), order.Strategy);
Assert.AreEqual(20, order.FeeAmount);