以下に示すようなデータベース関係があります。ドメイン オブジェクトは、LINQ to SQL ORM に基づいて作成されます。
支払いは、現金支払いとギフト クーポン支払いで構成されます。購入総額が550であるとします。次のコンポーネントとして支払うことができます
1 Gift Coupon Valued 300
1 Gift Coupon Valued 200
I Cash Currency Valued 50
ORM の「InsertOnSubmit」機能を使用して、新しい支払いレコードを挿入しています。次のコードは正常に動作しています。ただし、会社がクレジット カードを使用する新しい支払いコンポーネントを導入する場合、「支払い」ドメイン クラスを変更する必要があります。ORMを引き続き使用して、支払クラスOpen for Extension および Closed for Changesを作成するにはどうすればよいですか?
注: Payment クラスには動作があります(例: GetTotalAmountCollected)。OCPを満たすために「Payment」クラスを作ろうとしています。
注:クーポン タイプには特定の動作があります。クーポンの発行日が 2000 年 1 月 1 日より前の場合、合計金額の計算に使用しないでください (つまり、CouponValue はゼロにする必要があります)。ストラテジー パターンを使用したコードのリファクタリングも参照してください。
注:.Net 4.0を使用しています
参照:
- Entity Framework で ObjectContext.AddObject を使用するとエラーが発生する
- 戦略パターンを使用したコードのリファクタリング
- 継承よりも構成を優先しますか?
- コードファースト vs モデル/データベースファースト
- Unity を使用した戦略パターンと依存性注入
- デリゲートと OOP による C# ストラテジー デザイン パターン
- C# で戦略パターンを使用するには?
- EF Code First による継承: パート 2 – タイプごとのテーブル (TPT) http://weblogs.asp.net/manavi/archive/2010/12/28/inheritance-mapping-strategies-with-entity-framework-code-first -ctp5-part-2-table-per-type-tpt.aspx
C# コード:
public class PaymentAppService
{
public RepositoryLayer.ILijosPaymentRepository Repository { get; set; }
public void MakePayment()
{
DBML_Project.Payment paymentEntity = new DBML_Project.Payment();
paymentEntity.PaymentID = 1;
paymentEntity.PaymentType = "PurchaseP";
DBML_Project.CashPayment cashObj = new DBML_Project.CashPayment();
cashObj.CashPaymentID = 1;
cashObj.CurrencyNumber = 123;
cashObj.CurrencyValue = 100;
DBML_Project.GiftCouponPayment giftCouponObj = new DBML_Project.GiftCouponPayment();
giftCouponObj.GiftCouponPaymentID = 1;
giftCouponObj.CouponValue = 200;
giftCouponObj.CouponNumber = 124;
paymentEntity.CashPayments = new System.Data.Linq.EntitySet<DBML_Project.CashPayment>();
paymentEntity.CashPayments.Add(cashObj);
paymentEntity.GiftCouponPayments = new System.Data.Linq.EntitySet<DBML_Project.GiftCouponPayment>();
paymentEntity.GiftCouponPayments.Add(giftCouponObj);
Repository.InsertEntity(paymentEntity);
Repository.SubmitChanges();
}
}
リポジトリ:
public class LijosPaymentRepository : ILijosPaymentRepository
{
public System.Data.Linq.DataContext MyDataContext { get; set; }
public void InsertEntity(DBML_Project.Payment payment)
{
//Insert the entity
MyDataContext.GetTable<DBML_Project.Payment>().InsertOnSubmit(payment);
}
public void SubmitChanges()
{
MyDataContext.SubmitChanges();
}
}