让我们看一下接口驱动的抽象工厂的另一个场景
在开始之前,我们需要清楚接口指定了需要做什么,并带有输入和所需输出的微妙指示。也就是说,它并不强制要求输入和输出都需要很好地定义,因为它们本身也可以被视为合同。如果我们不完全清楚输入和输出的结构是什么,我们可以使用标记接口;那些根本没有任何结构的..
假设我们有一个购物车,我们需要提供付款选项。常见的选择是网上银行、信用卡和贝宝。让我们有这个场景的定义
public interface ICustomerAccountInformation { }
public interface IPaymentClient { } // Identifies whom the payment is intended for
public interface ITransactionDetails : IPaymentClient { } // Identifies amount, beneficiary details to be reflected in customer account
public interface IPaymentStatus { }
public interface IPaymentProvider {
IPaymentStatus ProcessPayment(ICustomerAccountInformation customerInfo, ITransactionDetails transaction);
}
public class PayPal : IPaymentProvider {
public IPaymentStatus ProcessPayment(ICustomerAccountInformation customerInfo, ITransactionDetails transaction) {
/* Open paypal's login page,
do its own checks and process payment.
Once successfull, send back to referrer with the payment status
*/
}
public class NetbankingProvider : IPaymentProvider {
public IPaymentStatus ProcessPayment(ICustomerAccountInformation customerInfo, ITransactionDetails transaction) {
/* Redirect to bank selection
redirect to bank's login page,
do its own checks and process payment.
Once successfull, send back to referrer with the payment status
*/
}
在整个流程中,每个提供者都可以自由询问所需的任何信息(有些只是获取凭据,而另一些则要求提供 OTP 作为附加信息)。他们还根据自己的结构返回状态。然而,在逻辑层面上,如果支付成功与否,他们会获取用户的凭据并返回一条消息
您可以将工厂设计为独立于任何其他供应商设计。只需在每个合同上都有标记接口。
在执行 DI 代码(例如NInject)时,使用“ WhenInjectedInto ”或类似构造将正确的实现注入到正在使用的每个提供程序中。您的工厂将根据用户的选择可供使用,而不会影响您的核心业务流程。
DI的主要规则是从核心业务中完全抽象出非核心业务。核心业务不应该关心每个提供商的期望,只是对预期的功能有一个模糊的想法。标记界面最适合此要求,尤其是当您已经开始设计但还不完全清楚时。随着您对所涉及的过程更加清晰,您可以稍后改进标记界面。
如果您需要进一步了解设计,请告诉我。