商家:
我有一个支付系统,可以通过GiftCoupon,ClubMembershipCard等支付。一个支付本身可以有多个支付组件
班级:
我有一个付款类。它有支付组件,如GiftCouponPayment,ClubMembershipCardPayment,CashPayment等。每种组件类型都满足通用接口IPaymentComponent。我使用有关现有类型的知识实现了它。
问题
1)如何以抽象方式实现此功能 - 不知道存在哪些类型?这意味着它需要适用于实现IPaymentComponent接口的所有类型。
2)如果无法在LINQ to SQL中实现它,是否可以在实体框架中实现?
3)当 LINQ to SQL 在Payment对象中生成GiftCouponPayment实体时,它是关联/聚合还是组合?
注意:我使用LINQ to SQL作为ORM。 GiftCouponPayment和Payment是自动生成的类,这些对象由ORM创建。我通过使用部分类为这些类添加了更多功能。
注意:在数据库中,每个PaymentComponent(例如GiftCouponPayment)都有自己的属性(例如CouponValue,CardValue等)。因此,每层次表层次不会很好。我们需要单独的表格。那条线上有解决方案吗?
注意:此付款之前,数据库中已存在GiftCouponPayment。我们需要使用客户提供的GiftCouponPaymentID来识别GiftCouponPayment对象。我们只需要更新此表中的PaymentID列。
漏洞抽象是指任何已实现的抽象,旨在减少(或隐藏)复杂性,其中底层细节未被完全隐藏
LINQ to SQL Diagram
参考:
C#CODE
public interface IPaymentComponent
{
int MyID { get; set; }
int MyValue { get; set; }
int GetEffectiveValue();
}
public partial class GiftCouponPayment : IPaymentComponent
{
public int MyID
{
get
{
return this.GiftCouponPaymentID;
}
set
{
this.GiftCouponPaymentID = value;
}
}
public int MyValue
{
get
{
return this.CouponValue;
}
set
{
this.CouponValue = value;
}
}
public int GetEffectiveValue()
{
if (this.CouponNumber < 2000)
{
return 0;
}
return this.CouponValue;
}
}
public partial class Payment
{
public List<IPaymentComponent> AllPaymentComponents()
{
List<IPaymentComponent> allPayComps = new List<IPaymentComponent>();
List<GiftCouponPayment> giftCouponPaymentList = new List<GiftCouponPayment>();
List<CashPayment> cashPaymentList = new List<CashPayment>();
foreach (GiftCouponPayment g in this.GiftCouponPayments)
{
giftCouponPaymentList.Add(g);
allPayComps.Add(g);
}
foreach (CashPayment c in this.CashPayments)
{
cashPaymentList.Add(c);
allPayComps.Add(c);
}
return allPayComps;
}
}
答案 0 :(得分:1)
您可以尝试使用类型为T的泛型的抽象层或数据访问层。或者至少使方法通用。
答案 1 :(得分:1)
我想你可能想暂时离开设计。我听到的是:
付款由一个或多个组件组成,每个组件可以是各种类型之一
你需要的是一个Payment
表,然后是一个PaymentComponent
表,其外键关系回到Payment
表。然后,您可以在PaymentComponent
表上实现继承,以用于各种付款方式。
答案 2 :(得分:1)
如何为付款类型建模
让我们假设我们想要采用经典的OOP方式:
你需要一个基类,付款(或PaymentBase)是抽象的,并且需要从中继承的各种类,例如PaymentInCash,PaymentWithCreditCard等
另一种方法是将PaymentDetails添加到Payment并创建PaymentDetails的层次结构,如果您选择这样做,则在以下所有点中将Payment与PaymentDetails替换。
对于使用多种方法的付款,您可以:
一个。在付款下有一系列PaymentDetails
或
湾创建一个名为AggregatePayment的类型,其中包含付款清单。
如何将付款类型映射到表格
TPT和TPH都在这里有效......
对于TPT 使用一个表格进行付款,使用一个表格进行各种付款 所有继承类型的表PK应该是基本类型表的FK 如果您有多个层次结构,如果使用EF,则可以在第二个(或任何其他)级别使用TPT或TPH。
对于TPH 使用一个带有鉴别器列的表(例如PaymentType),并将层次结构中所有实体之间未共享的每个列标记为可空。不要对不同实体中的不同属性使用相同的列。在EF中,将每个实体映射到同一个表,条件为PaymentType =(数字在此处)和(不应为空的列名称)不为空。
我的建议是,如果你有很多窄类型(每个属性很少),请选择TPH,如果你有几种宽类型,请选择TPT。
支付算法使用哪种设计模式/代码技术
您有更多选择:
一个。使用部分类并在基类上放置一个抽象的ProcessPayment()方法,并在继承类中重写。
湾每种付款类型使用基本PaymentProcessor类和特定的PaymentProcessor,例如PaymentInCashProcessor。在这种方法中,您可以使用反射来加载正确的PaymentProcessor类型,方法是使用泛型来存储词典或更好:
abstract class PaymentProcessor
{
}
abstract class PaymentProcessor<TPayment> : PaymentProcessor
where TPayment : class, Payment
{
}
class PaymentInCashProcessor : PaymentProcessor<PaymentInCash>
{
}
// Use reflection to find types that inherits from PaymentProcessor<PaymentInCash>
// create an instance of the type you found
// then cast the instance to PaymentProcessor<PaymentInCash> to use
abstract class PaymentProcessor
{
}
abstract class PaymentProcessor<TPayment> : PaymentProcessor
where TPayment : class, Payment
{
}
class PaymentInCashProcessor : PaymentProcessor<PaymentInCash>
{
}
// Use reflection to find types that inherits from PaymentProcessor<PaymentInCash>
// create an instance of the type you found
// then cast the instance to PaymentProcessor<PaymentInCash> to use
答案 3 :(得分:0)
如果您设计EF模型,则可以在名为payment的基类上使用abstract属性。并继承您所有类别的付款方式:
付款将包含所有常见属性,并且每种特定类型都可以拥有自己的属性。
如果你有这种模式,你可以查询付款。
这将返回继承付款类型的所有对象:
var allPayments = objectContext.Payments;