【Groovy】MOP 元对象协议与元编程 ( 方法委托 | 批量方法委托 )
文章目錄
- 一、批量方法委托
- 二、完整代碼示例
一、批量方法委托
在上一篇博客 【Groovy】MOP 元對(duì)象協(xié)議與元編程 ( 方法委托 | 正常方法調(diào)用 | 方法委托實(shí)現(xiàn) | 代碼示例 ) 中 , 將 StudentManager 對(duì)象的方法委托給了其內(nèi)部的 student1 和 student2 成員 , 在 methodMissing 方法中進(jìn)行方法委托 , 需要使用 student.respondsTo(name, args) 代碼 , 逐個(gè)判斷調(diào)用的方法是否在 student1 或 student2 成員中 ; 如果 StudentManager 中定義了很多成員 , 那么就需要逐個(gè)進(jìn)行判定 , 寫起來很繁瑣 ;
下面介紹一種實(shí)現(xiàn)方法委托的方式 , 可以優(yōu)雅的處理上述問題 ;
在 StudentManager 中實(shí)現(xiàn)
def delegate(Class... classes)方法 , 方法接收可變長(zhǎng)度的 Class 對(duì)象作為參數(shù) ;
首先 , 通過反射 , 創(chuàng)建委托對(duì)象 ;
def objects = classes.collect{// 通過反射創(chuàng)建要委托的對(duì)象it.newInstance()}然后 , 通過 HandleMetaClass 注入 methodMissing 方法 ;
// 注入方法需要獲取 org.codehaus.groovy.runtime.HandleMetaClass 對(duì)象進(jìn)行注入StudentManager sm = thissm.metaClass.methodMissing = {String name, def args ->}再后 , 在 objects 數(shù)組中查找哪個(gè)對(duì)象中包含 name(args) 方法 , 返回該對(duì)象賦值給 object 對(duì)象 ; 該步驟確保被代理類中有指定的方法 ;
// 在 objects 數(shù)組中查找哪個(gè)對(duì)象中包含 name(args) 方法// 返回該對(duì)象賦值給 object 對(duì)象def object = objects.find{it.respondsTo(name, args)}最后 , 如果最終找到的 object 方法不為空 , 則向 StudentManager 中注入相應(yīng)方法 , 然后調(diào)用該注入的方法 ;
if (object) {// 注入 name 方法sm.metaClass."$name" = {object.invokeMethod(name, it)}// 調(diào)用剛注入的方法invokeMethod(name, args)}方法委托實(shí)現(xiàn)如下 :
class StudentManager{{// 代碼塊中調(diào)用 delegate 方法 , 傳入要委托的類delegate(Student1, Student2)}/*** 實(shí)現(xiàn)方法委托* @param classes 可變長(zhǎng)度的 Class 對(duì)象*/def delegate(Class... classes) {def objects = classes.collect{// 通過反射創(chuàng)建要委托的對(duì)象it.newInstance()}// 注入方法需要獲取 org.codehaus.groovy.runtime.HandleMetaClass 對(duì)象進(jìn)行注入StudentManager sm = thissm.metaClass.methodMissing = {String name, def args ->// 在 objects 數(shù)組中查找哪個(gè)對(duì)象中包含 name(args) 方法// 返回該對(duì)象賦值給 object 對(duì)象def object = objects.find{it.respondsTo(name, args)}if (object) {// 注入 name 方法sm.metaClass."$name" = {object.invokeMethod(name, it)}// 調(diào)用剛注入的方法invokeMethod(name, args)}}} }二、完整代碼示例
完整代碼示例 :
class Student1{def hello1(){println "hello1"} }class Student2{def hello2(){println "hello2"} }class StudentManager{{// 代碼塊中調(diào)用 delegate 方法 , 傳入要委托的類delegate(Student1, Student2)}/*** 實(shí)現(xiàn)方法委托* @param classes 可變長(zhǎng)度的 Class 對(duì)象*/def delegate(Class... classes) {def objects = classes.collect{// 通過反射創(chuàng)建要委托的對(duì)象it.newInstance()}// 注入方法需要獲取 org.codehaus.groovy.runtime.HandleMetaClass 對(duì)象進(jìn)行注入StudentManager sm = thissm.metaClass.methodMissing = {String name, def args ->// 在 objects 數(shù)組中查找哪個(gè)對(duì)象中包含 name(args) 方法// 返回該對(duì)象賦值給 object 對(duì)象def object = objects.find{it.respondsTo(name, args)}if (object) {// 注入 name 方法sm.metaClass."$name" = {object.invokeMethod(name, it)}// 調(diào)用剛注入的方法invokeMethod(name, args)}}} }def sm = new StudentManager()// 方法委托, 直接通過 StudentManager 對(duì)象調(diào)用 Student1 中的方法 sm.hello1() // 方法委托, 直接通過 StudentManager 對(duì)象調(diào)用 Student2 中的方法 sm.hello2()/*方法委托 : 如果調(diào)用的某個(gè)對(duì)象方法沒有定義該對(duì)象 , 則可以將該方法委托給內(nèi)部對(duì)象執(zhí)行*/執(zhí)行結(jié)果 :
hello1 hello2總結(jié)
以上是生活随笔為你收集整理的【Groovy】MOP 元对象协议与元编程 ( 方法委托 | 批量方法委托 )的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【Git】将 GitHub 工程设置为私
- 下一篇: 【Groovy】编译时元编程 ( 编译时