这里可以使用什么模式来预览这个结果



我有一个下单的方法,

public async Task<bool> Order(Request request)
{
// Each step does different things.
await Step1(request);
await Step2(request);
await Step3(request);
await Step4(request);
...
await StepN(request);
}
public async Task<bool> Step1(Request request)
{
var amount1 = await changeSomething1(request);
await Pay1(amount1);
}
public async Task<bool> Step2(Request request)
{
var amount2 = await changeSomething2(request);
await Pay2(amount2);
}
public async Task<bool> StepX(Request request)
{
var amountX = await changeSomethingX(request);
await PayX(amountX);
}

现在我需要在没有调用任何PayX(amount)的情况下预览订单。我不想添加一个boolen参数来跳过它,就像下面的代码一样,它看起来很难看。

public async Task<bool> Order(Request request, bool preview = false)
{
await Step1(request, preview);
await Step2(request, preview);
await Step3(request, preview);
await Step4(request, preview);
....
await StepN(request, preview);
}
public async Task<bool> StepX(Request request, bool preview = false)
{
var amountX = await changeSomethingX(request);
if(!preview) await PayX(amountX);
}

这里可以应用什么模式?非常感谢。

在我看来,您需要一些类似中间件的模式(例如Asp.Net中的中间件(。这是我的建议:

首先创建一个OrderMiddleware类,它封装了您的两个方法,Step和Pay。在这种情况下,我们将步骤和付款作为委托给构造函数,以实现最大的灵活性

public delegate Task<int> StepDelegate(Request request);
public delegate Task PayDelegate(int amount);
public class OrderMiddleware
{
// Private fields
private readonly StepDelegate _step;
private readonly PayDelegate _pay;

// Initialization
public OrderMiddleware(StepDelegate step, PayDelegate pay)
{
_step = step;
_pay = pay;
}

// Public
public async Task Order(Request request, bool preview)
{
var amount = await _step.Invoke(request);
if (!preview)
await _pay.Invoke(amount);
}
}

然后,您需要一个类来处理一个OrderMiddlewares列表,该列表表示您的完整管道。

public class OrderPipeline
{
// Private fields
private readonly List<OrderMiddleware> _orderMiddlewares;

// Initialization
public OrderPipeline()
{
_orderMiddlewares = new()
{
new(Step1, Pay1),
new(Step2, Pay2)
};
}

// Order Handling
public async Task Order(Request request, bool preview = false)
{
foreach(var middleware in _orderMiddlewares)
await middleware.Order(request, preview);
}

// Middlewares
public async Task Step1(Request request)
{
var amount1 = await changeSomething1(request);
await Pay1(amount1);
}
public async Task Step2(Request request)
{
var amount2 = await changeSomething2(request);
await Pay2(amount2);
}
}

通过这种方式,order方法可以处理中间件列表。只有几个注意事项:

如果您需要向每个中间件传递其他参数,请考虑创建一个OrderConfiguration类来封装所有这些数据,然后传递它。通过这种方式,签名保持干净,您不需要进行任何重构

也许您想将中间件注册逻辑与OrderPipeline类分离,以避免违反开放-关闭原则:

public class OrderPipeline
{
// Private fields
private readonly List<OrderMiddleware> _orderMiddlewares = new();

// Order Handling
public async Task Order(Request request, bool preview = false)
{
foreach(var middleware in _orderMiddlewares)
await middleware.Order(request, preview);
}
public void AddMiddleware(OrderMiddleware orderMiddleware)
{
_orderMiddlewares.Add(orderMiddleware);
}
}

最新更新