我们需要动态支持多种支付方式(信用卡、PayPal、Google Pay 等...)。
我们可以更改用于实现某种支付方式的网关。
例如:
今天可以使用 Stripe SDK 实现 PayPal 付款方式,明天可以使用 PayPal SDK 实现。
这让我想到了策略模式,我可以通过任何网关 sdk 来实现每种支付方式。
示例::
class PayPalModel : IPaymentModel
class PayPalGateway(val someSdk: SDK) : IPaymentService<PayPalModel> {
override suspend fun authorizeFunds(model: PayPalModel) {
// someSdk can be: stripe sdk, paypal sdk, ...
}
}
然后简单地注入服务,并调用“authorizeFunds”:
val gateways =
listOf(
CreditGateway(),
PayPalGateway()
)
val api = PaymentAPI(gateways)
api.authorizeFunds(PayPalModel(...)
然后“api”将首先在内部找到正确的服务:
private suspend fun findService(model: IPaymentModel): IPaymentService<IPaymentModel>? {
for (service in paymentServices) {
if (service.appliesTo(model)) {
return service as IPaymentService<IPaymentModel>
}
}
return null
}
但是,对于我们支持的所有付款方式,在下订单时,客户端仅向服务器发送两个字段:
因此,在这种情况下,各种支付模型(PayPalModel、CreditModel,..)似乎是多余的,因为它们始终包含相同的数据。
但是,如果我们忽略或概括此模型,我们将失去所有类型的网关实现之间的类型安全区别。
例如,想象一下:
class PayPalGateway : IPaymentService { // omiting the model
override suspend fun authorizeFunds(model: PaymentRequest) {
/// stripe sdk, paypal sdk, ...
}
}
class CreditGateway : IPaymentService<PaymentRequest> { // generalizing the model
override suspend fun authorizeFunds(model: PaymentRequest) {
/// stripe sdk, paypal sdk, ...
}
}
因此,除了类命名之外,没有真正的方法可以“安全地”区分服务以便使用正确的服务。 上面的“findService”功能将被破坏/无用。 确保当客户端向我发送方法类型+令牌/id时,我选择正确的支付服务,明智的选择是什么?
enum class PaymentType {
PAY_PAL, CREDIT, ...
}
interface IPaymentModel {
val type: PaymentType
}
我想,该客户向您提供了有关他们的付款方式/服务的信息。这样,您只需检查该值并选择正确的网关即可。
when(model.type) {
PAY_PAL -> // return the PayPal service class
}
在我看来,这种方法比迭代可用服务更稳健。