元编程(动态类、方法合成与委托)

2020-06-19  本文已影响0人  lv_mock

动态类

def expando = new Expando(name:'zhangshan',fun1:{'fun1'})
expando.size = 100
expando.fun2 = {
    "fun2"
}

println expando.name
println expando.size
println expando.fun1()
println expando.fun2()
//output:
zhangshan
100
fun1
fun2

方法合成

class Person {
    def methodMissing(String name,def args) {
         "missing"
    }
}
def person = new Person()
println person.dpop()
//output
missing
class Person {
    def methodMissing(String name, def args) {
        println 'missing'

        if (name.startsWith("play")) {
            println metaClass //MetaClassImpl
            Person p = this
            println p.metaClass //HandleMetaClass 要在HandleMetaClasss上注入方法
            p.metaClass."$name" = {
                println "invoke $name"
            }
            "$name"(args)
        }

    }
}

def person = new Person()
println person.metaClass //HandleMetaClass
person.playGame()
person.playGame()
//output:
org.codehaus.groovy.runtime.HandleMetaClass@7188af83[groovy.lang.MetaClassImpl@7188af83[class Person]]
missing
groovy.lang.MetaClassImpl@7188af83[class Person]
org.codehaus.groovy.runtime.HandleMetaClass@7188af83[groovy.lang.MetaClassImpl@7188af83[class Person]]
invoke playGame
invoke playGame

方法委托

class Work1 {
    def fun1 () {
        println "fun1"
    }

    def methodMissing(String name,def args) {
        println 'fun1 missing'
    }
}

class Work2 {
    def fun2 () {
        println "fun2"
    }

    def methodMissing(String name,def args) {
        println 'fun2 missing'
    }
}


class WorkManager {
    Work1 work1 = new Work1()
    Work2 work2 = new Work2()

    def methodMissing(String name,def args) {
        WorkManager wm = this
        if(work1.respondsTo(name,args)) {
            work1.invokeMethod(name,args)
        }else  if(work2.respondsTo(name,args)) {
            work2."$name"(args)
        } else {
            println 'missing'
        }
    }
}

def wm = new WorkManager()


wm.fun1()
wm.fun2()
wm.fun3()
//output:
fun1
fun2 missing
missing
class Work1 {
    def fun1 () {
        println "fun1"
    }

    def methodMissing(String name,def args) {
        println 'fun1 missing'
    }
}

class Work2 {
    def fun2 () {
        println "fun2"
    }

    def methodMissing(String name,def args) {
        println 'fun2 missing'
    }
}


class WorkManager {
    Work1 work1 = new Work1()
    Work2 work2 = new Work2()

    def methodMissing(String name,def args) {
        WorkManager wm = this
        if(work1.respondsTo(name,args)) {
            wm.metaClass."$name" = {
                work1.invokeMethod(name,args)
            }
            "$name"(args)
        }else  if(work2.respondsTo(name,args)) {
            wm.metaClass."$name" = {
                work2.invokeMethod(name,it)
            }
            "$name"(args)
        } else {
            println 'missing'
        }
    }
}

def wm = new WorkManager()


wm.fun1()
wm.fun2()
wm.fun3()
//output
fun1
fun2
missing
class Work1 {
    def fun1() {
        println "fun1"
    }

    def methodMissing(String name, def args) {
        println 'fun1 missing'
    }
}

class Work2 {
    def fun2() {
        println "fun2"
    }

    def methodMissing(String name, def args) {
        println 'fun2 missing'
    }
}


class WorkManager {
    {
        delegete(Work1,Work2)
    }

    def delegete(Class... classes) {
        def objects = classes.collect { it.newInstance() };
        WorkManager wm = this;
        wm.metaClass.methodMissing = {
            String name,def args ->
                def object = objects.find {
                    it.respondsTo(name,args)
                }
                if(object) {
                    wm.metaClass."$name" = {
                        object.invokeMethod(name,it)
                    }
                    "$name"(args)
                }
        }

    }
}

def wm = new WorkManager()
wm.fun1()
wm.fun2()
//output
fun1
fun2
class Work1 {
    def fun1() {
        println "fun1"
    }

    def methodMissing(String name, def args) {
        println 'fun1 missing'
    }
}


class WorkManager {
    @Delegate Work1 work1  = new Work1()
}
new WorkManager().fun1()
//output
fun1
上一篇 下一篇

猜你喜欢

热点阅读