好吧,假设我正在制作一个花哨的网上商店。
我有一个支付服务提供商(比如,paypal),要求用户登录paypal网站,确认凭据,然后将他重定向到我的网站。
所以基本上背后的代码看起来像这样:
class PaymentManager
{
public string AcceptPayment(Payment payment)
{
//return redirect url
}
public bool ConfirmPayment(string paymentToken)
{
//if token is valid the payment succeded
}
}
所以基本上我的控制器使用这个管理器映射到2个控制器方法(每个都需要一个单独的请求)。
现在,假设我有一个不同的付款管理器,这需要按顺序执行3个方法,而不是2.像:
class AnotherPaymentManager
{
public string AcceptPayment(Payment payment)
{
//return validation redirect url
}
public string ValidatePayment(string validationCode)
{
//return redirect url
}
public bool ConfirmPayment(string paymentToken)
{
//if token is valid, confirm payment
}
}
现在这个类的用法映射到3个控制器方法(我们需要客户端执行Accept
方法来声明付款,然后执行Validate
方法来验证它,然后执行Confirm
方法确保服务器已接受它。)
问题是:如果这些管理员有不同的API使用场景来做同样的事情(如上所示),有没有办法在它们和控制器之间建立一个抽象层?我的意思是:
interface IPaymentManager
{
void MakePayment(); //this controls the payment methods flow
//Something like (Accept -> Confirm) in the former case
//and (Accept -> Validate -> Confirm) in the latter
}
我在ASP.NET WebAPI 2中这样做,但我认为它也可能适用于MVC。
答案 0 :(得分:2)
如果我理解正确,当用户创建交易时,他们会被重定向到支付提供商(在响应中使用重定向网址)。在那里,他们确认他们的凭证,将他们返回到你的花哨的网上商店(带有支付提供商提供的确认令牌)。如果该令牌有效,则交易成功。此外,每个操作都需要控制器中的单独端点。
如果这些假设是正确的,我会说没有必要,甚至不建议在这里创建一个抽象。此外,还有来自支付提供商的响应数据(validationCode,paymentToken等),您的PaymentManger功能和控制器端点依赖于该数据,以便继续进行。
根据我的经验,过早抽象可以为你做更多的工作。如果没有更多信息(支付提供商客户端的更多实现),您可能会进行过于具体的抽象 - 这些抽象不能用于您稍后添加的不同PaymentManager类型。
但是,如果你已经拥有这些数据(validationCode等),那么你可以在这里抽象,但我仍然认为这是不必要的,并且可能浪费时间。
如果您决定在此抽象,那么您可以在每个PaymentManager类中实现您的界面。让每个PaymentManger实现MakePayment函数,该函数将调用各自的PaymentManager函数。
同样,我不建议在这里抽象。它没有意义,在我看来真的不会那么有用。等到你再实现几个PaymentManager类。然后,您将能够更准确地查看不同类型的PaymentMangers之间的模式,并将这些模式抽象出来。
如果我对问题的理解不正确,请告诉我在哪里误解了问题,我会再次尝试回答。
在旁注中,如果您尚未调查外部API,我建议您查看asynchronous functions and the await operator。
希望这有帮助。