【问题标题】:What coding or design patterns can I use to enforce a required sequence of method calls?我可以使用哪些编码或设计模式来强制执行所需的方法调用序列?
【发布时间】:2016-03-12 20:33:54
【问题描述】:

我写了以下几行代码:

$this->validate($group);

$this->em->persist($group);
$this->em->flush();

如果 $group 无效,方法“validate”将抛出异常。问题是,它似乎有点“脆弱”。如果其他开发人员更改了这段代码,他可能会不小心移动了 validate 方法,而实体管理器会将对象保存到数据库中而不进行验证。

您认为以下代码行更好还是我只是想多了?

$validGroup = $this->validate($group);

$this->em->persist($validGroup);
$this->em->flush();

是否有任何验证模式?

【问题讨论】:

  • 写一个测试检查 validate 在persist之前被调用
  • 很明显测试会发现它,但假设测试不是一个选项。

标签: design-patterns anti-patterns


【解决方案1】:

Template Pattern 适合这个问题。

在模板模式中,抽象类公开定义的方式/模板来执行其方法。它的子类可以根据需要覆盖方法实现,但调用方式与抽​​象类定义的方式相同。此模式属于行为模式类别。

abstract class MyTemplate{
   void myPersist(){
      validate();
      persist();
      flush();
}

【讨论】:

    【解决方案2】:

    我会在persist 内部进行验证,这样就不可能持久化未验证的对象。如果em 是第三方代码并且您不想更改它,请将em 包装在您自己的对象中,该对象在写入数据库之前进行验证并在任何地方使用它。

    有几个选项可用于设计em 或您的包装器,这样您只需编写一次就可以在程序的任何地方使用单个实例。你可以

    • 赋予被持久化的对象验证自身的责任,例如要求所有可持久对象具有 is_valid 方法。 em 或者您的包装器会要求对象验证自身并在对象无效时抛出异常。如果您能够为可持久对象添加行为,这可能是最好的解决方案,因为它将有效性的概念与数据放在同一位置。

    • em 或您的包装器检测到对象的类型,查找(在注册表中或通过命名约定)知道如何验证该类型对象的验证器对象,要求验证器验证对象被持久化,如果对象无效,再次抛出异常。这更复杂,但如果验证足够复杂,值得一个单独的对象,或者如果您无法向可持久对象添加行为,则可能会有所帮助。

    【讨论】:

    • 这不会导致我需要一个 em 包装器来处理我想要持久化和验证的每种类型的对象吗?
    • 我扩展了我的答案,讨论了两种不存在该问题的验证策略。
    • 第二个选项似乎更好,即使我对如何在不增加任何复杂性的情况下解决它感到好奇,我也会将其标记为答案。假设我有一个不那么常见的方法,并且简单地具有:methodThatHaveToBeCalledFirst() 和 methodThatHaveToBeCalledSecond() ...您要做什么(不增加复杂性)来避免这种情况? (并且都返回 void)
    • 我说的很简单。如果您想强制执行该编码顺序,则它需要位于某个地方:持久性管理器、持久化对象或两者兼而有之。因此,更多的复杂性只是伴随着需求而来。
    【解决方案3】:

    这个问题涉及到界面设计中一个非常重要且意义重大的问题。问题是“未声明的顺序”,即方法调用的顺序是隐含的和未声明的。它是许多问题和混乱的根源。

    有两种方法可以重构它(至少)。上面都已经提供了,我只是总结一下。

    1. 使用一个方法调用的结果作为另一个调用的输入(就像 OP 已经做的那样)。这确保了秩序。当第一个方法调用的结果被多次使用时,它是适用且有用的。
    2. 在第二个方法中调用第一个方法(反之亦然)。这也将解决问题,因为界面的用户必须调用单个方法。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-12-20
      • 2014-09-03
      • 1970-01-01
      • 2018-06-03
      • 1970-01-01
      • 2015-12-12
      • 1970-01-01
      • 2019-06-17
      相关资源
      最近更新 更多