【问题标题】:Design Patterns for dependent sequential validation依赖顺序验证的设计模式
【发布时间】:2020-12-10 11:28:35
【问题描述】:

我有三个验证器,每个验证器依次依赖于前一个。我可能会使用所有三个或仅使用前两个或仅使用第一个。例如

  1. 验证器 1:检查用户是否存在
  2. 验证器 2:检查请求的订单是否存在于用户的订单历史记录中
  3. 验证器 3:检查该订单是否有取消选项

如果不满足前一个条件,此列表中的每个验证器都会抛出错误。我目前正在使用这种模式:

function validator1() { ... }

function validator2() { validator1(); ... }

function validator3() { validator2(); ... }

但这对我来说感觉像是一种反模式,因为所有先决条件验证都是隐式完成的,所以当我运行 validtor2() 时,并不清楚 validator1() 是否也在运行。

我也考虑过这样做:

function validator1() { ... }

function validator2() { ... }

function validator3() { ... }

function someTask() { validator1(); validator2(); validator3(); ... }

但这是不安全的,因为没有什么能阻止我运行 validator3() 并在条件 2 未满足时抛出错误。

有没有一种既安全又明确的方法来做到这一点?

编辑

这是公认答案中提到的设计模式的一个很好的参考:https://refactoring.guru/design-patterns/chain-of-responsibility

【问题讨论】:

    标签: function validation design-patterns coding-style refactoring


    【解决方案1】:

    我建议研究 责任链Builder 模式 专门用于验证。 见这里:

    您还可以查看装饰器模式的用法:

    有没有一种既安全又明确的方法来做到这一点?

    但是在考虑其中一种模式当然可能会提供更大的灵活性但也更复杂之前,请考虑您的规则是否真的可以得到很多扩展并且将被重用以及在很多情况下。否则,立即使用建议的模式之一可能有点过度设计。

    此外,您还可以通过使用有意义的函数名称来进行大量解释,这些函数名称明确地告诉代码的读者正在执行什么特定的用例。这样的功能更像是所需验证步骤的协调器。因此,您的方法(尽管名称不好 someTask())可能已经满足您的需求。

    但这是不安全的,因为没有什么能阻止我运行 validator3() 并在条件 2 未满足时抛出错误。

    如果其中一个验证失败,您可以让每个验证异常抛出一个异常,或者引入具有主要任务返回的保护子句。

    另一种选择是传入或注册具有相同接口的验证列表并循环它们。如果您需要检查所有验证并收集每个验证步骤的结果(例如错误代码或消息),或者在第一次验证时抛出异常,则取决于您的需要。

    【讨论】:

      猜你喜欢
      • 2011-05-08
      • 2019-12-11
      • 1970-01-01
      • 2012-01-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-06-15
      相关资源
      最近更新 更多