我似乎经常遇到这样的情况:我有一个抽象类型,需要根据它具有的具体实现进行不同的处理。
举个例子,抽象类 Payment
可以被子类化为 class CreditCard
或 class StoredCredit
。为了实际处理付款,我们希望使用
interface IPaymentTaker {
PaymentProcessingResult Process(Payment payment); }
即要么
class CreditCardPaymentTaker : IPaymentTaker { ... }
或
class StoredCreditPaymentTaker : IPaymentTaker { ... }
过去我已经将 IDictionary 注入(inject)到父组件中然后完成
_paymentTakers[payment.GetType()].Process(payment);
这样做的缺点是 IPaymentTaker
实现的类型不够强,因此 Process 方法的第一位必须是:
Process(Payment payment)
{
var creditCardPayment = payment as CreditCardPayment;
if (creditCardPayment == null)
throw new Exception("Payment must be of type CreditCard");
}
我确信我正在尝试实现的模式必须有一个名称,但我不知道它是什么!
理想情况下我会
(a) 能够仅根据付款类型实例化 PaymentProcessor,而无需创建字典;
(b) 能够拥有只接受它们可以使用的子类的强类型 PaymentProcessors。
有人有解决这个问题的好方法吗?
最佳答案
您可以使用visitor来解决这个问题:
interface IPaymentVisitor {
void Visit(CreditCard payment);
void Visit(StoredCredit payment);
}
abstract class Payment {
public abstract void Accept(IPaymentVisitor visitor);
}
class CreditCard : Payment {
public override void Accept(IPaymentVisitor visitor) {
visitor.Visit(this);
}
}
class StoredCredit : Payment {
public override void Accept(IPaymentVisitor visitor) {
visitor.Visit(this);
}
}
class PaymentTaker : IPaymentVisitor, IPaymentTaker {
public void Visit(CreditCard payment) {
// ...
}
public void Visit(StoredCredit payment) {
// ...
}
public PaymentProcessingResult Process(Payment payment) {
payment.Accept(this);
// ...
}
}
如果您仍想将不同的付款接受者分开,或者您的层次结构不稳定,则可以使用 acyclic visitor (pdf) :
interface IPaymentVisitor {
}
interface IPaymentVisitor<TPayment> : IPaymentVisitor where TPayment : Payment {
void Visit(TPayment payment);
}
abstract class Payment {
public abstract void Accept(IPaymentVisitor visitor);
}
class CreditCard : Payment {
public override void Accept(IPaymentVisitor visitor) {
if (visitor is IPaymentVisitor<CreditCard>) {
((IPaymentVisitor<CreditCard>)visitor).Visit(this);
}
}
}
class StoredCredit : Payment {
public override void Accept(IPaymentVisitor visitor) {
if (visitor is IPaymentVisitor<StoredCredit>) {
((IPaymentVisitor<StoredCredit>)visitor).Visit(this);
}
}
}
class CreditCardPaymentTaker : IPaymentVisitor<CreditCard>, IPaymentTaker {
public void Visit(CreditCard payment) {
// ...
}
public PaymentProcessingResult Process(Payment payment) {
payment.Accept(this);
// ...
}
}
class StoredCreditPaymentTaker : IPaymentVisitor<StoredCredit>, IPaymentTaker {
public void Visit(StoredCredit payment) {
// ...
}
public PaymentProcessingResult Process(Payment payment) {
payment.Accept(this);
// ...
}
}
关于c# - 给定泛型类型参数的类型,动态选择组件的类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3424154/