【问题标题】:Is there a Java design pattern for the problem I am trying to solve?我要解决的问题是否有 Java 设计模式?
【发布时间】:2011-09-15 18:50:39
【问题描述】:

我有一个包含 Product 对象数组的数据模型。在从此模型报告之前,我需要运行一组规则来检查模型中每个 Product 对象的完整性。我能想到的一种方法是使用 Rule 接口,例如

public interface CheckRule {
    boolean runRule(Product p);
}

对于每个规则,我可以有一个单独的 Rule 类来实现 CheckRule 接口。然后我可以有一个双循环来运行所有规则,例如:

for (Product p : Products) {
   for (Rule r : Rules) {
      if (! r.runRule(p) {
              // report on the broken rule
      }
   }
}

如果我有数百个规则,但我最终会得到数百个规则类,这似乎是一种混乱的方式。另一种方法是有一个 RuleManager 类,它为每个规则都有一个单独的方法,例如

public class RuleManager {

    boolean runRule1(Product p) { // rule 1 logic}

    boolean runRule2(Product p) { // rule 2 logic}

    boolean runRule3(Product p) { // rule 3 logic}

    etc...
}

这减少了类的数量,但意味着我最终得到了一个包含数百个方法的类。这两种方法我都觉得不对,我想知道是否有一种设计模式可以涵盖这种情况,我可以使用它来代替吗?

【问题讨论】:

  • 我不明白如何避免拥有一个包含很多方法的非常大的 RuleManager 类或许多小类。如果您必须用 Java 编写规则,我看不到另一种方法。也许如果你可以用一些简单的语言来表达规则,你可以用规则编写一个文本文件,让 Java 在运行时解析和应用规则。这是一个选项吗?
  • 有些规则需要相当复杂的逻辑,在文本文件中很难表达。我不介意参加很多课程,只要我不会错过获得相同结果的更好方法。
  • 在我看来,这就像组合器是所描述的解决方案的情况。您的函数将从 Product 变为布尔值。你可以在这里得到一个想法,它真的很有用:github.com/raganwald/homoiconic/blob/master/2008-11-07/…
  • 谢谢安德烈亚斯,有时间我会看看你的文章。

标签: java interface model design-patterns


【解决方案1】:

规范设计模式可以解决你的问题。

http://en.wikipedia.org/wiki/Specification_pattern

【讨论】:

  • 这就是这个问题的答案。
【解决方案2】:

模式?框架...

例如

【讨论】:

  • 是的,Omnaest 的意思是,Java Validation API 的一个实现是 HIbernate Validator
【解决方案3】:

查找 Java 验证 API:

http://www.infoq.com/news/2010/03/javaee6-validation

它带有大量已经构建的验证器,您可以通过使用某些注释(例如 @ZipCode 和 @NotNull)简单地添加您的 bean 属性来使用它们,它让您可以轻松地声明自定义验证器以及您希望它们验证的内容,所有的脚手架都已经在那里了。

【讨论】:

  • 感谢 Andrei,我查看了验证 API。它适用于一些更简单的规则,但不能处理我需要应用的更复杂的规则。
  • 正如我所说,验证 API 允许您创建自定义验证器(作为非常简单的 calasses),然后通过注释将它们附加到某些 bean 属性。
【解决方案4】:

我想你会发现你经常可以参数化规则,这样你就不需要每个规则一个类。如果您愿意考虑使用反射,则尤其如此。

JSR303,又名 Java Validation API,适用于简单的字段验证,但当您需要做更复杂的事情时很快就会失去动力。

Drools 不相关,如果我理解用例的话 - 太重了。

仔细考虑如何处理验证错误。您希望能够报告多个错误 - 不要对第一个错误进行救助,您的用户会讨厌您。因此,您可能希望拥有某种错误收集器对象,验证器将错误放入其中,然后由验证器框架返回。

【讨论】:

  • 谢谢 Ed,我正在考虑创建一个 Rule id 列表,我可以对其进行迭代并使用反射根据规则 id 实例化每个 Rule 对象。如果您能详细说明我如何结合参数/反射来减少类的数量,我将不胜感激。
  • 大多数情况下,我正在考虑只查看一两个字段并且在许多类的许多字段中通用的规则。例如,一个简单的 min-max 规则可能具有所需的 min、max 以及要检查的字段的名称或 getter-Method 作为参数。
  • 我可以看到使用字段名称作为参数可能会有所帮助。可能有几个规则都只访问一个字段,我可以在一个类中包含所有这些规则。给我一些工作。
【解决方案5】:

将规则作为单独的类似乎更好。将它们组织成有意义的包层次结构以减轻精神负担。

将许多验证方法捆绑到一个类中会使该类变得沉重。最终,您希望将该类拆分为多个类,每个类有一个入口点(并可能传递一个验证回调,该回调会接收有关失败规则的通知)。但是,将单个规则隐藏起来对外界来说会很好,这会使测试变得困难。

【讨论】:

  • 谢谢罗恩,我认为多班是我要去的方式。
【解决方案6】:

基本上,当您有一组对象(在您的情况下是产品集合)需要对其进行一组操作(在您的情况下检查每个产品的完整性)时,您必须使用访问者模式。模式的标准实现需要对每种产品类型进行一次操作(我假设您对每种产品类型都有单独的类)。但如前所述,您可能会以某种方式减少在产品层次结构中执行子类化并为该层次结构树的某些分支指定一些参数的方法的数量。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-09-09
    • 2011-02-26
    • 2014-04-03
    • 2023-04-06
    • 1970-01-01
    • 2021-01-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多