【Groovy】MOP 元对象协议与元编程 ( 方法委托 | 批量方法委托 )

简介: 【Groovy】MOP 元对象协议与元编程 ( 方法委托 | 批量方法委托 )

一、批量方法委托


在上一篇博客 【Groovy】MOP 元对象协议与元编程 ( 方法委托 | 正常方法调用 | 方法委托实现 | 代码示例 ) 中 , 将 StudentManager 对象的方法委托给了其内部的 student1 和 student2 成员 , 在 methodMissing 方法中进行方法委托 , 需要使用 student.respondsTo(name, args) 代码 , 逐个判断调用的方法是否在 student1 或 student2 成员中 ; 如果 StudentManager 中定义了很多成员 , 那么就需要逐个进行判定 , 写起来很繁琐 ;

下面介绍一种实现方法委托的方式 , 可以优雅的处理上述问题 ;


在 StudentManager 中实现

def delegate(Class... classes)

方法 , 方法接收可变长度的 Class 对象作为参数 ;


首先 , 通过反射 , 创建委托对象 ;

def objects = classes.collect{
            // 通过反射创建要委托的对象
            it.newInstance()
        }

然后 , 通过 HandleMetaClass 注入 methodMissing 方法 ;

// 注入方法需要获取 org.codehaus.groovy.runtime.HandleMetaClass 对象进行注入
        StudentManager sm = this
        sm.metaClass.methodMissing = {
            String name, def args ->
  }


再后 , 在 objects 数组中查找哪个对象中包含 name(args) 方法 , 返回该对象赋值给 object 对象 ; 该步骤确保被代理类中有指定的方法 ;

// 在 objects 数组中查找哪个对象中包含 name(args) 方法
                // 返回该对象赋值给 object 对象
                def object = objects.find{
                    it.respondsTo(name, args)
                }


最后 , 如果最终找到的 object 方法不为空 , 则向 StudentManager 中注入相应方法 , 然后调用该注入的方法 ;

if (object) {
                    // 注入 name 方法
                    sm.metaClass."$name" = {
                        object.invokeMethod(name, it)
                    }
                    // 调用刚注入的方法
                    invokeMethod(name, args)
                }


方法委托实现如下 :

class StudentManager{
    {
        // 代码块中调用 delegate 方法 , 传入要委托的类
        delegate(Student1, Student2)
    }
    /**
     * 实现方法委托
     * @param classes 可变长度的 Class 对象
     */
    def delegate(Class... classes) {
        def objects = classes.collect{
            // 通过反射创建要委托的对象
            it.newInstance()
        }
        // 注入方法需要获取 org.codehaus.groovy.runtime.HandleMetaClass 对象进行注入
        StudentManager sm = this
        sm.metaClass.methodMissing = {
            String name, def args ->
                // 在 objects 数组中查找哪个对象中包含 name(args) 方法
                // 返回该对象赋值给 object 对象
                def object = objects.find{
                    it.respondsTo(name, args)
                }
                if (object) {
                    // 注入 name 方法
                    sm.metaClass."$name" = {
                        object.invokeMethod(name, it)
                    }
                    // 调用刚注入的方法
                    invokeMethod(name, args)
                }
        }
    }
}

二、完整代码示例


完整代码示例 :

class Student1{
    def hello1(){
        println "hello1"
    }
}
class Student2{
    def hello2(){
        println "hello2"
    }
}
class StudentManager{
    {
        // 代码块中调用 delegate 方法 , 传入要委托的类
        delegate(Student1, Student2)
    }
    /**
     * 实现方法委托
     * @param classes 可变长度的 Class 对象
     */
    def delegate(Class... classes) {
        def objects = classes.collect{
            // 通过反射创建要委托的对象
            it.newInstance()
        }
        // 注入方法需要获取 org.codehaus.groovy.runtime.HandleMetaClass 对象进行注入
        StudentManager sm = this
        sm.metaClass.methodMissing = {
            String name, def args ->
                // 在 objects 数组中查找哪个对象中包含 name(args) 方法
                // 返回该对象赋值给 object 对象
                def object = objects.find{
                    it.respondsTo(name, args)
                }
                if (object) {
                    // 注入 name 方法
                    sm.metaClass."$name" = {
                        object.invokeMethod(name, it)
                    }
                    // 调用刚注入的方法
                    invokeMethod(name, args)
                }
        }
    }
}
def sm = new StudentManager()
// 方法委托, 直接通过 StudentManager 对象调用 Student1 中的方法
sm.hello1()
// 方法委托, 直接通过 StudentManager 对象调用 Student2 中的方法
sm.hello2()
/*
    方法委托 : 如果调用的某个对象方法没有定义该对象 , 则可以将该方法委托给内部对象执行
 */


执行结果 :

hello1
hello2

image.png

目录
相关文章
|
存储 安全 Linux
OpenSSH之Windows账户访问操作
OpenSSH之Windows账户访问操作
927 0
|
6月前
|
人工智能 自然语言处理 搜索推荐
销售易CRM:深度赋能企业销售全流程
销售易CRM是国内领先的客户关系管理系统,助力企业实现销售全流程自动化、数据驱动精准决策、跨部门高效协作及个性化定制。通过智能线索培育、实时数据分析、无缝系统集成与灵活业务调整,大幅提升销售效率与客户体验。结合AI技术与全面服务支持,销售易CRM成为企业数字化转型的可靠伙伴,推动企业在竞争中脱颖而出。
|
6月前
|
运维 监控 安全
IDS 和 IPS 日志监控的重要性
本文介绍了入侵检测系统(IDS)与入侵防御系统(IPS)在企业网络安全中的重要作用及区别。IDS通过监控网络流量、识别异常活动并生成警报,采用异常检测和签名检测等方法保障安全;而IPS作为自动化设备,主动分析流量并阻止恶意攻击,同时重新配置防火墙以增强防护能力。两者协同工作可实时抵御威胁,并通过日志记录和分析优化安全策略。此外,卓豪EventLog Analyzer能有效监控和分析IDS/IPS日志,助力企业精准识别复杂威胁,提升整体网络安全水平。
133 0
|
12月前
|
消息中间件 监控 开发工具
微服务(三)-实现自动刷新配置(不重启项目情况下)
微服务(三)-实现自动刷新配置(不重启项目情况下)
|
10月前
|
API
全国行政区划查询免费API接口教程
该接口提供全国(不含港澳台)各级行政区划查询服务,适用于地址填写、资料登记等场景。支持5级划分:省、市、区县、乡镇、村。请求需提供用户ID、KEY及查询级别等参数,返回地名列表或错误信息。 示例中ID和KEY为公共测试用,建议使用个人ID和KEY以享受更高调用频率。
1612 23
AutoJS4.1.0实战教程---火山极速版
AutoJS4.1.0实战教程---火山极速版
120 0
Python基础语法:运算符详解(算术运算符、比较运算符、逻辑运算符、赋值运算符)
运算符是Python编程中的重要组成部分,理解并熟练使用这些运算符有助于编写高效、简洁的代码。本文详细介绍了算术运算符、比较运算符、逻辑运算符和赋值运算符的使用方法,并通过综合示例展示了它们在实际编程中的应用。希望通过本文的介绍,您能更好地掌握Python中的运算符。
426 13
|
关系型数据库 数据库 数据安全/隐私保护
"告别繁琐!Python大神揭秘:如何一键定制阿里云RDS备份策略,让数据安全与效率并肩飞,轻松玩转云端数据库!"
【8月更文挑战第14天】在云计算时代,数据库安全至关重要。阿里云RDS提供自动备份,但标准策略难以适应所有场景。传统手动备份灵活性差、管理成本高且恢复效率低。本文对比手动备份,介绍使用Python自定义阿里云RDS备份策略的方法,实现动态调整备份频率、集中管理和智能决策,提升备份效率与数据安全性。示例代码演示如何创建自动备份任务。通过自动化与智能化备份管理,支持企业数字化转型。
233 2
|
存储 监控 数据管理
屏幕监控软件中的APL数组处理
**摘要:** 本文探讨了APL在屏幕监控软件中的数据处理作用,强调其在处理复杂数据结构和大量信息时的效率。文中通过三个示例展示了APL的数组操作能力:计算平均值、筛选异常值和计算标准差。此外,还讨论了如何用APL脚本自动化将处理后的监控数据提交到网站,以实现高效、实时的数据管理和安全性。APL为需要高效数据处理的场景提供了简洁而强大的工具。**
174 2
|
存储 消息中间件 数据挖掘
数据仓库的深度探索与实时数仓应用案例解析
大数据技术的发展,使得数据仓库能够支持大量和复杂数据类型(如文本、图像、视频、音频等)。数据湖作为一种新的数据存储架构,强调原始数据的全面保留和灵活访问,与数据仓库形成互补,共同支持企业的数据分析需求。