按顺序调用多个API的设计模式



我正在做与支付服务的集成。我还得登上一艘商船。要登录商家,我需要遵循以下步骤

  1. 创建支付服务用户,如果创建成功:POST api call
  2. 创建上一步中创建的用户的业务配置文件:POST api call
  3. 为用户创建支付配置文件:POST api call
  4. 注册一个回调url,用于接收webhook的交易状态更改,用于该用户的支付:POST api调用

如果任何步骤失败,我只需要从该步骤重试。我不能从头开始。

我的解决方案:

我正在维护一个状态对象,用于用户的登录。状态对象有4个字段

  • userCreated
  • businessProfileCreated
  • paymentProfileCreated
  • webhookRegistered

每一步我设置各自的状态属性为真,并保存它。

Algotithm:

初始化状态对象all

state.userCreated = false;
state.businessProfileCreated = false;
state.paymentProfileCreated = false;
state.webhookRegistered = false;`
if(state.userCreated != true)
create user
if create profile **not** success
save state 
return
state.userCreated = true
if(state.businessProfileCreated != true)
create business profile
if businessProfile creation  **not** success
save state
return
state.businessProfileCreated = true

如果状态。= true创建支付配置文件如果支付配置文件创建成功保存状态返回state.paymentProfileCreated

如果状态。webhookRegistered != true):创建webhook配置文件保存状态返回

state.paymentProfileCreated保存状态">

我需要一个干净的方式来做这件事,也处理api失败。是否存在此任务的模式

也许其他人有更好的想法,但我想到的是策略模式的修改版本。(参见https://en.wikipedia.org/wiki/Strategy_pattern)

要实现这一点,你需要一个要执行的函数列表(策略),你需要编写一些代码来遍历列表,调用函数,检查结果,并通过存储失败函数的索引来跟踪错误发生的位置,而不是使用一堆布尔标志。

如果您决定使用这种模式,您的问题是不同的函数可能需要不同的参数,并且使事情更加复杂的是,某些函数可能依赖于先前调用的函数返回的某些结果。要解决这个问题,您必须将这些函数可能需要的所有信息存储到一个单独的对象中,并将该对象传递给每个函数,以便它们可以根据需要从该对象中读取字段并向其写入字段。

这可能是不值得的麻烦,它可能不会让读者更清楚正在发生什么。

考虑保持现有代码的结构,只是改进它,例如:

  • 使用一个枚举来告诉你你走了多远,而不是一堆布尔值;

  • 移动新函数中的所有步骤,并修改每个错误检查,使其返回失败指示,而不是保存状态然后返回。然后,从调用该函数的地方,检查它是否指示错误,如果是,只在一个地方保存状态。

这是可以使用状态模式的地方。正如wiki所说:

状态模式是一种行为软件设计模式,允许对象在其内部状态改变时改变其行为。此模式接近有限状态机的概念

让我来演示一下如何通过c#实现它。

这是一个将按顺序运行多个API的类:

public class APIMachine
{
IState _userState;
IState _callbackState;
IState _paymentState;
IState _businessState;
public string Run() 
{
_userState = InitializeState();
_userState.Do();
return _callbackState.GetResult().ToString();
}
private IState InitializeState() 
{
_callbackState = new CallbackState();
_paymentState = new PaymentState(_callbackState);
_businessState = new BusinessState(_paymentState);
return new UserState(_businessState);
}
}

这是所有状态的抽象:

public interface IState
{
void Do();
bool HasSuccess { get; set; }
int RetryCount { get; }
object GetResult();
}

这是UserState的一个具体实现:

public class UserState : IState
{
IState _state;
public UserState(IState state) => _state = state;
public int RetryCount => 3;
public bool HasSuccess { get ; set ; }
public void Do()
{
int count = 0;
while (count <= RetryCount)
{
// Make post request here to create user
HasSuccess = true;
if (HasSuccess)
{
_state.Do();
break;
}
count++;
}
}
public object GetResult()
{
throw new NotImplementedException();
}
}

:

public class BusinessState : IState
{
IState _state;
public BusinessState(IState state) => _state = state;
public int RetryCount => 3;
public bool HasSuccess { get; set; }
public void Do()
{
int count = 0;
while (count <= RetryCount)
{
// Make post request here to create business profile
HasSuccess = true; // if post request is okay
if (HasSuccess)
{
_state.Do();
break;
}
count++;
}
}
public object GetResult()
{
throw new NotImplementedException();
}
}

:

public class PaymentState : IState
{
IState _state;
public PaymentState(IState state) => _state = state;
public int RetryCount => 3;
public bool HasSuccess { get; set; }
public void Do()
{
int count = 0;
while (count <= RetryCount)
{
// Make post request here to create payment profile
HasSuccess = true; // if post request is okay
if (HasSuccess) 
{
_state.Do();
break;
}
count++;
}
}
public object GetResult()
{
throw new NotImplementedException();
}
}

:

public class CallbackState : IState
{
public int RetryCount => 3;
public bool HasSuccess { get; set; }
public void Do()
{
int count = 0;
while (count <= RetryCount)
{
// Make post request here to create payment profile
HasSuccess = true; // if post request is okay
if (HasSuccess)
{
break;
}
count++;
}
}
public object GetResult()
{
return "foobar.com";
}
}

上面的代码可以这样运行:

APIMachine apiMachine = new();
string callbackUri = apiMachine.Run();

输出:foobar.com

最新更新