如何在java中进行链式检查

2023-12-07

考虑一个像下面这样的类

public class MyClass {

    private Integer myField;
    private Result result;
    // more global variables

    public MyResult check(Integer myParameter) {
        init(myParameter);

        if (myField < 0) {
            result.setErrorMessage("My error message");
            return result;
        }

        // a lot more 'checks' like above where something may be written
        // to the error message and the result gets returned.
    }

    private void init(Integer myParameter) {
        result = new Result();
        result.setExistsAnnouncement(/*search a certain object via crudService with myParameter*/);
        // initialize other global variables including myField
    }

}

问题是check上面的方法太长并且有很多return声明。我想到了一些重构,但仍然不确定该怎么做。我正在考虑类似链条图案的东西。然后,我将实现几个检查器类,它们要么调用链中的下一个检查器,要么返回result与相应的errorMessage.

但后来我有了一个更好的想法(至少我这么认为):为什么不像 java 8 那样表现呢?我想用类似的东西Try-Success-Failure-图案。但我不知道如何实现这一点。我在想这样的事情:

entrancePoint.check(firstChecker)
    .check(secondChecker)
    .check // and so on

这个想法是:当check失败,它会表现得像Optional.map()并返回类似的东西Optional.EMPTY(或者在这种情况下类似Failure). When check成功后应该继续进行下一个检查(返回Success).

你有做这样的事情的经验吗?


当我们考虑验证时,它通常是复合模式。它大致被描述为:

如果这是有效的,那么就做一些事情.

当您强加时,您想要将多个检查器链接在一个链中以在其区域中执行验证,您可以实现一个责任链图案。

考虑一下:

你可以有一个Result对象,可以包含有关失败的消息以及简单的真/假。

你可以有一个Validator对象,执行所需的任何验证并返回一个实例Result.

public interface Result {  
    public boolean isOk();
    public String getMessage();
}

// We make it genric so that we can use it to validate
// any type of Object that we want.
public interface Validator<T> {
    public Result validate(T value);
}

现在,当您说要使用多个检查器验证“X”时,您是在强加一个验证规则那只不过是一个集合Validator对象同时是一个实例Validator本身。话虽如此,您不能再使用Result对象检查规则的验证结果。你将需要一个复合材料Result可以将结果保持为的对象{Validator=Result}。它看起来不像是一个实现HashMap<Validator, Result>?是的,因为确实如此。

现在您可以实施您的Rule and CompositeResult as:

public class Rule extends ArrayList<Validator> implements Validator {

    public Rule(Validator<?> ... chain) {
        addAll(Arrays.asList(chain));
    }

    public Object validate(Object target) {
        CompositeResult result = new CompositeResult(size());
        for (Validator rule : this) {
            Result tempResult = rule.validate(value);
            if (!tempResult.isOk())
                result.put(rule, tempResult);
        }
        return result;
    }
}

public class CompositeResult extends HashMap<Validator, Result> implements
        Result {

    private Integer appliedCount;

    public CompositeResult(Integer appliedCount) {
        this.appliedCount = appliedCount;
    }

    @Override
    public boolean isOk() {
        boolean isOk = true;
        for (Result r : values()) {
            isOk = r.isOk();
            if (!isOk)
                break;
        }
        return isOk;
    }

    @Override
    public String getMessage() {
        return toString();
    }

    public Integer failCount() {
        return size();
    }

    public Integer passCount() {
        return appliedCount - size();
    }

}

就是这样!现在,要实现您的检查器:

public class Checker1 implements Validator<Integer> {
    /* Implementation */
}

public class CheckerN implements Validator<Integer> {
    /* Implementation */
}

现在是进行验证的时候了:

Validator<Integer> checkingRule = new Rule(new Checker1(), new CheckerN());
CompositeResult result = checkingRule.validate(yourParameter);
if (result.isOk()) 
    System.out.println("All validations passed");
else
    System.out.println(result.getFailedCount() + " validations failed");

简单又整洁。

我已经上传了一个我的公共仓库中的示例供你玩耍。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何在java中进行链式检查 的相关文章

随机推荐

  • Python - 使用 pandas 多重处理多个大尺寸文件

    我有一个y csv文件 文件大小为 10 MB 包含来自Jan 2020 to May 2020 我每个月还有一个单独的文件 例如data 2020 01 csv 它包含详细的数据 每个月文件的文件大小约为1 GB 我正在分割y csv按月
  • GUI 在循环时变得无响应

    单击按钮后 表单将变得无响应 直到解析函数完成其工作 我想将 searchAll 函数移至线程 我确实阅读了类似问题的几个答案 但我不明白如何 class MyForm QDialog def init self super init se
  • 连接到 SFTP 服务器时出现 SocketException:名称有效,但未找到请求类型的数据

    我正在尝试使用 SharpSsh 库连接我的 sftp 服务器 但出现以下错误 System Net Sockets SocketException 0x80004005 The requested name is valid but no
  • Flutter 在本机应用程序中打开本地资源(PDF)

    我正在尝试将我的应用程序与 PDF 捆绑在一起 并让用户在本机查看器中打开它 我努力了 将 PDF 的数据复制到 临时目录 或 文档目录 来自 path provider 并从那里打开 要打开 我使用 url launcher 打开文件 我
  • 使用 angular2 限制输入字段的长度

    我已经实现了使用 angular2 限制输入字段的指令 它在桌面浏览器中工作正常 但在 Android 移动设备中无法工作 成分 import LimitToDirective from directives limitedvalidati
  • 按两个变量组进行汇总

    考虑一个简化的数据集 真实的数据集有更多的列和行 df tp tf weight 1 FWD RF 78 86166 2 MF LF 81 04566 3 DEF LF 80 70527 4 DEF LF 82 96071 5 DEF RF
  • 如何将position_dodge()和geom_line()与重叠分组结合起来?

    当 x 轴上的分组变量 颜色和线条重叠但总是不同时 是否可以使用 geom line 在躲避点之间绘制一条线 下图中的灰线应该始终连接两个具有相同名称的数据点 它们位于相同的分组 2 x 轴 内 但位于不同的分组 2 颜色 中 可重现的例子
  • 如何在silverstripe数据扩展中自动发布图像

    我试图将上传字段添加到自定义数据扩展并让图像字段正常工作 但是 我上传的图像仍处于概念模式 我必须转到 文件 选项卡才能发布它 我尝试使用 Silverstripe 文档中提供的代码 但这似乎只适用于常规页面 我发现了一个和我类似的问题 如
  • 在 .htaccess 中使用自定义环境变量

    我需要这样的东西 SetEnv foo bar baz RewriteEngine On RewriteCond HTTP HOST foo RewriteRule http www foo 1 L UPD 我做了如下 SetEnv HOS
  • Struts 2 文件上传 - 空指针异常

    我正在尝试结合使用 Struts2 和 Spring 来上传文件 但是 不知怎的 在到达我的动作课 我的文件之后 filename和文件内容类型都出来了null 我尝试寻找问题所在 但没有结果 下面是我的文件上传的代码 index jsp
  • 如何使用 Mockito 和 JUnit 检查方法中的 if 语句?

    我有我应该测试的方法 代码 当然有些部分被删掉了 public class FilterDataController public static final String DATE FORMAT yyyy MM dd Autowired p
  • 在docker下安装时可以回答对话框问题吗?

    是否可以以某种方式回答使用 apt get 安装某些软件包时以对话框形式出现的问题 例如 我正在尝试设置一个包含以下内容的容器mail stack delivery包装内含 FROM ubuntu RUN apt get install y
  • 如何在android中使用sax解析器从xml读取imageUrl在网格视图中显示图像

    我是安卓新手 我想创建一个应用程序来从 URL 读取 XML 文件并使用图像的 ImageUrl 在网格视图中显示图像 感谢您的回答 但我可以从 url 读取 xml 文件 但我需要 xml imageUrl 是否存在 以便在网格视图中显示
  • 计算原始输入中的元音数

    我有一个家庭作业问题 要求通过原始输入读取字符串并计算字符串中有多少个元音 这是我到目前为止所拥有的 但我遇到了一个问题 def vowels vowels a e i o u count 0 string raw input Enter
  • 运行“sudo pip”有哪些风险?

    偶尔我会遇到评论或回应该状态强调运行pip under sudo是 错误 或 坏 但在某些情况下 包括我设置一堆工具的方式 它要么更简单 要么甚至有必要以这种方式运行 跑步有哪些风险pip under sudo 请注意 这与以下问题不同th
  • 在定义整个映射之前,如何引用映射中的变量?

    我将从我的代码开始 因为它应该更容易理解我想要做什么 function get color color lightness return map get map get colors color lightness colors green
  • Thread.MemoryBarrier 和简单属性的锁区别

    对于以下场景 有什么区别吗关于使用之间的线程安全性 结果和性能MemoryBarrier private SomeType field public SomeType Property get Thread MemoryBarrier So
  • 在 Python 中使用 pynput 检查特定键

    dpressed 0 def on press key if key d global dpressed dpressed 1 logging info D s dpressed 当我运行此代码并按 d 时 没有任何反应 我怀疑这是因为在检
  • Python - isnull().sum() 与 isnull().count()

    所以我目前正在完成泰坦尼克号数据集的教程 https www kaggle com c titanic data 现在我正在尝试一些可能相关的新事物 The info for it is There are 891 entries red
  • 如何在java中进行链式检查

    考虑一个像下面这样的类 public class MyClass private Integer myField private Result result more global variables public MyResult che