对于我试图解决的问题,是否有Java设计模式?

对于我试图解决的问题,是否有Java设计模式?,java,interface,model,design-patterns,Java,Interface,Model,Design Patterns,我有一个包含产品对象数组的数据模型。在此模型中报告之前,我需要运行一组规则来检查模型中每个产品对象的完整性。我能想到的一种方法是有一个规则接口,例如 public interface CheckRule { boolean runRule(Product p); } 对于每个规则,我可以有一个单独的规则类来实现CheckRule接口。然后我可以使用双循环运行所有规则,例如: for (Product p : Products) { for (Rule r : Rules) {

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

public interface CheckRule {
    boolean runRule(Product p);
}
对于每个规则,我可以有一个单独的规则类来实现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...
}
这减少了类的数量,但意味着我最终得到了一个包含数百个方法的类。我觉得这两种方法都不对,我想知道是否有一种设计模式涵盖了这个场景,我可以用它来代替?

模式?框架

例如

  • JSR303-bean验证->
  • 规则引擎->

查找Java验证API:


它附带了大量已构建的验证器,您只需使用某些注释(如@ZipCode和@NotNull)添加bean属性的注释即可使用这些验证器,并且它可以让您轻松声明自定义验证器以及您希望它们验证的内容,您已经拥有了所有的脚手架。

规范设计模式可能会解决您的问题


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

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

如果我理解用例的话,流口水是不相关的——太重了


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

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


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

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

是的,Omnaest说的是,Java验证API的一个实现是HIbernate Validator,我不知道如何避免拥有一个包含大量方法的非常大的RuleManager类,或者许多小型类。如果必须用Java编写规则,我看不到其他方法。如果您可以用一些简单的语言来表达这些规则,您可以用这些规则编写一个文本文件,并让Java在运行时解析和应用这些规则。这是一个选项吗?有些规则需要相当复杂的逻辑,这很难在文本文件中表达。我不介意有很多类,只要我没有错过一些更好的方法来获得相同的结果。在我看来,这就像一个例子,其中描述的解决方案是组合子。您的函数将从乘积到布尔值。你可以在这里得到一个想法,它真的很有用:谢谢Andreas,我有时间的时候会看看你的文章。谢谢Ed,我正在考虑拥有一个规则id列表,我可以迭代并使用反射根据规则id实例化每个规则对象。如果您能详细介绍一下如何组合参数/反射以减少类的数量,我将不胜感激。大多数情况下,我正在考虑的规则只关注一个或两个字段,并且对于许多类中的许多字段都是通用的。例如,一个简单的min-max规则可能将所需的min、max以及要检查的字段的名称或getter方法作为参数。我可以看到使用字段名称作为参数会有什么帮助。可能有几个规则都只访问一个字段,我可以在一个类中包含所有这些规则。给了我一些可以使用的东西。谢谢Andrei,我看了一下验证API。它适用于一些简单的规则,但不能处理我需要应用的更复杂的规则。正如我所说的,验证API允许您创建自定义验证器(作为非常简单的calass),然后通过注释将这些验证器附加到某些bean属性。谢谢ron,我想我会选择多节课,这就是这个问题的答案。