讲师中心 微信公众号
AI工具推荐 视频效率加速

Groovy中利用闭包重构相似条件等待方法

云涛君_8060

云涛君_8060

发布时间:2025-11-05 16:18:01

|

444人浏览过

|

来源于php中文网

原创

groovy中利用闭包重构相似条件等待方法

本文旨在探讨如何通过Groovy的闭包特性,将功能相似但条件判断逻辑不同的重复方法合并为一个通用方法。我们将演示如何构建一个可配置的 `waitUntil` 方法,它接受一个闭包来封装动态的条件检查,从而有效减少代码冗余,并优化了在循环中创建临时对象的潜在性能问题。

在软件开发中,我们经常会遇到这样的场景:多个方法执行着几乎相同的操作流程,但它们的核心差异仅在于等待某个条件满足的具体判断逻辑。这种模式往往导致代码冗余和维护困难。例如,考虑以下两个Groovy方法:

def someCondition = false

def method1() {
    while(!someCondition) {
        def connectionStatus = getConnectionStatus() // return 200, 404, etc.
        if (connectionStatus == 200) {
            someCondition = true
        } else {
            println "repeat until connection is 200"
            sleep 15
        }
    }
}

def method2(){
    while(!someCondition) {
        def result = getResult() // A, B, C, etc. 
        if (result in ["A", "B", "C"]) {
            someCondition = true
        } else {
            println "waiting until result is either A, B, or C"
            sleep 15
            result = getResult() // call again to check if result changed
        }
    }
}

这两个方法都包含一个 while 循环,用于等待某个条件变为真,并在每次检查失败后暂停一小段时间。它们的主要区别在于 if 语句内部的条件判断逻辑。method1 检查 connectionStatus 是否为 200,而 method2 检查 result 是否在 ["A", "B", "C"] 列表中。这种重复的结构显然可以通过抽象来优化。

利用闭包实现通用等待机制

Groovy的闭包(Closure)提供了一种优雅的方式来封装代码块并将其作为参数传递。我们可以利用这一特性,创建一个通用的 waitUntil 方法,将具体的条件判断逻辑作为闭包传入。

首先,我们定义一个基础的 waitUntil 方法,它接受一个返回布尔值的闭包作为 test 参数:

def waitUntil(int sleepMs = 100, int maxRetries = 60, Closure<Boolean> test) {
    int retries = 0
    while (retries++ < maxRetries && !test()) {
        println "尝试 ${retries}/${maxRetries} 次失败,等待 ${sleepMs} 毫秒后重试..."
        Thread.sleep(sleepMs)
    }
    if (retries > maxRetries) {
        println "已达到最大重试次数,条件未满足。"
        return false // 或者抛出异常
    }
    println "条件已满足!"
    return true
}

这个 waitUntil 方法包含以下参数:

  • sleepMs (int, 默认 100): 每次重试失败后暂停的毫秒数。
  • maxRetries (int, 默认 60): 最大重试次数。
  • test (Closure): 一个闭包,它不接受参数并返回一个布尔值。当此闭包返回 true 时,表示条件已满足,等待结束。

现在,我们可以使用这个通用方法来替代之前的 method1 和 method2:

HTML5技术开发服务解决公司网站模板
HTML5技术开发服务解决公司网站模板

HTML5技术开发服务解决公司网站模板是一款提供为企业提供服务和解决方案的公司宣传网站模板下载。提示:本模板调用到谷歌字体库,可能会出现页面打开比较缓慢。

下载
// 模拟获取连接状态
def getConnectionStatus() {
    // 实际应用中可能是网络请求
    [404, 200, 404].random() // 随机返回状态码
}

// 模拟获取结果
def getResult() {
    // 实际应用中可能是某个计算结果
    ["X", "Y", "A", "Z"].random() // 随机返回结果
}

// 替代 method1 的调用
println "等待连接状态为 200..."
waitUntil(sleepMs: 1000, maxRetries: 10) {
    getConnectionStatus() == 200
}

// 替代 method2 的调用
println "\n等待结果为 A, B 或 C..."
waitUntil(sleepMs: 500, maxRetries: 20) {
    getResult() in ["A", "B", "C"]
}

通过这种方式,我们成功地将重复的等待逻辑抽象到一个方法中,而将变化的条件判断逻辑通过闭包动态注入。

优化闭包参数传递与性能考量

在上述实现中,如果闭包内部需要引用一些外部数据(例如 ["A", "B", "C"] 这样的列表),并且这个闭包会被频繁调用,那么每次调用时都重新创建这个列表可能会带来轻微的性能开销,尤其是在长时间运行或高频率调用的场景下。为了避免这种情况,我们可以将这些外部数据作为参数传递给 waitUntil 方法,并进一步传递给闭包。

优化后的 waitUntil 方法可以接受一个额外的参数 expectedValue,并将其作为参数传递给 test 闭包:

def waitUntil(Object expectedValue, int sleepMs = 100, int maxRetries = 60, Closure<Boolean> test) {
    int retries = 0
    while (retries++ < maxRetries && !test(expectedValue)) { // 将 expectedValue 传递给闭包
        println "尝试 ${retries}/${maxRetries} 次失败,等待 ${sleepMs} 毫秒后重试..."
        Thread.sleep(sleepMs)
    }
    if (retries > maxRetries) {
        println "已达到最大重试次数,条件未满足。"
        return false
    }
    println "条件已满足!"
    return true
}

现在,调用方式也需要相应调整,闭包可以使用 it 关键字来引用传入的参数:

// 模拟获取连接状态
def getConnectionStatus() {
    [404, 200, 404].random()
}

// 模拟获取结果
def getResult() {
    ["X", "Y", "A", "Z"].random()
}

// 示例:等待连接状态为 200
println "等待连接状态为 200 (优化版)..."
waitUntil(200, sleepMs: 1000, maxRetries: 10) { expected -> // expected 参数接收 200
    getConnectionStatus() == expected
}

// 示例:等待结果为 A, B 或 C
println "\n等待结果为 A, B 或 C (优化版)..."
waitUntil(["A", "B", "C"], sleepMs: 500, maxRetries: 20) { expectedList -> // expectedList 接收列表
    getResult() in expectedList
}

通过这种改进,像 ["A", "B", "C"] 这样的列表只在 waitUntil 方法调用时创建一次,而不是在每次闭包执行时都创建,从而提高了效率。

注意事项与总结

  • 错误处理: 在实际应用中,waitUntil 方法可能需要更健壮的错误处理机制,例如在达到最大重试次数后抛出特定异常,而不是简单地返回 false。
  • 线程安全: 如果 getConnectionStatus() 或 getResult() 等方法涉及共享状态或外部资源,需要确保其线程安全性。
  • 灵活性: 这种模式非常灵活,不仅限于等待外部资源,还可以用于等待内部状态的改变、UI元素的出现等多种场景。
  • 代码可读性: 尽管引入了闭包,但由于其简洁的语法和强大的表达能力,这种重构通常能提高代码的可读性和维护性。

通过利用Groovy的闭包特性,我们能够有效地将相似方法的重复逻辑进行抽象和封装,创建出高度可复用且灵活的通用方法。这不仅减少了代码冗余,提高了开发效率,还在一定程度上优化了潜在的性能问题,是Groovy编程中值得推崇的一种设计模式。

热门AI工具

更多
豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

Loomy
Loomy Hot

一款AI工具,主要用于科大讯飞发布的桌面级 AI 助理,比 OpenClaw 更易用、更安全!,适合需要提升相关任务效率的用户。

SkildArt
SkildArt Hot

SkildArt是一款AI文本写作工具,一站式 AI 视觉创作平台。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

小橡皮AI

一款AI工具,主要用于小橡皮一键去AI味,将机器味重的内容改得更有活人感,防止因为 AI 内容被平台打上 AI 标签,以及限流,适合需要提升相关任务效率的用户。

UP简历
UP简历 Hot

一款AI办公效率工具,主要用于基于AI技术的免费在线简历制作工具,适合需要提升相关任务效率的用户。

立刻MV
立刻MV Hot

立刻MV是一款AI文本写作工具,AI 音乐视频(MV)创作工具。

墨刀AI
墨刀AI Hot

一款AI图像与设计工具,主要用于产品经理的专属智能体,适合需要提升相关任务效率的用户。

相关专题

更多
while的用法
while的用法

while的用法是“while 条件: 代码块”,条件是一个表达式,当条件为真时,执行代码块,然后再次判断条件是否为真,如果为真则继续执行代码块,直到条件为假为止。本专题为大家提供while相关的文章、下载、课程内容,供大家免费下载体验。

354

2023.09.25

string转int
string转int

在编程中,我们经常会遇到需要将字符串(str)转换为整数(int)的情况。这可能是因为我们需要对字符串进行数值计算,或者需要将用户输入的字符串转换为整数进行处理。php中文网给大家带来了相关的教程以及文章,欢迎大家前来学习阅读。

6739

2023.08.02

int占多少字节
int占多少字节

int占4个字节,意味着一个int变量可以存储范围在-2,147,483,648到2,147,483,647之间的整数值,在某些情况下也可能是2个字节或8个字节,int是一种常用的数据类型,用于表示整数,需要根据具体情况选择合适的数据类型,以确保程序的正确性和性能。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

3245

2024.08.29

c++怎么把double转成int
c++怎么把double转成int

本专题整合了 c++ double相关教程,阅读专题下面的文章了解更多详细内容。

4208

2025.08.29

C++中int的含义
C++中int的含义

本专题整合了C++中int相关内容,阅读专题下面的文章了解更多详细内容。

2885

2025.08.29

线程和进程的区别
线程和进程的区别

线程和进程的区别:线程是进程的一部分,用于实现并发和并行操作,而线程共享进程的资源,通信更方便快捷,切换开销较小。本专题为大家提供线程和进程区别相关的各种文章、以及下载和课程。

4418

2023.08.10

go语言闭包相关教程大全
go语言闭包相关教程大全

本专题整合了go语言闭包相关数据,阅读专题下面的文章了解更多相关内容。

4613

2025.07.29

Vite 项目如何打包和部署
Vite 项目如何打包和部署

Vite项目打包部署专题汇集生产构建、产物预览、输出目录、资源路径、Nginx与GitHub Pages部署及常见白屏和路由404问题的已审核文章,帮助读者完成上线流程。

0

2026.10.28

Vite 如何搭配 Vue.js
Vite 如何搭配 Vue.js

Vite搭配Vue.js专题汇集创建Vue 3项目、配置开发环境、路径别名、Vue插件、代理、多环境构建与调试的已审核文章,帮助读者完成从初始化到日常开发的配置。

0

2026.10.28

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn