22 例子:元对象协议

1       例子:元对象协议

1.1  练习目标

使用MOP扩展类。

1.2  创建一个Groovy对象并返回所有方法和属性调用

创建一个Groovy类。当每个属性被访问时,会假装方法调用,并返回一个固定值。

package mop

 

class AnyMethodExecutor {

    //忽略了getter方法

    String value="Lars";

    //总是返回5,不管传入的是什么property

    Object getProperty(String property) {

       return 5;

    }

    void setProperty(String property,Object o) {

       //忽略

    }

    def methodMissing(String name,args) {

       def s = name.toLowerCase();

       if(!s.contains("hello")) {

           return "This method is just fake";

       } else {

           return "Still a fake method but 'hello' back to you.";

       }

    }

}

使用下边的Groovy脚本来测试该方法。

package mop

 

class AnyMethodExecutorTest {

 

    static main(args) {

       def test = new AnyMethodExecutor();

       //你能调用任何方法像下边这样

       assert "This method is just fake" == test.hall();

       assert "This method is just fake" == test.hallo();

       assert "Still a fake method but 'hello' back to you."==test.helloMethod();

       assert "Still a fake method but 'hello' back to you."==test.helloM();

       //以下基本的属性设置会被忽略

       test.test = 5;

       test.superDuperCool = 100;

       //所有的properties都会返回5

       assert test.superDuperCool == 5;

       assert test.value==5;

    }

 

}

1.3  练习: 向Groovy类中增加json输出,笨方法和聪明的方法

创建下边的Groovy类。

package mop.json

 

import groovy.json.JsonBuilder

 

class Task {

    String summary;

    String description;

   

    def methodMissing(String name,args) {

       if (name == "toJson") {

           JsonBuilder b1 = new JsonBuilder(this);

           return b1.toString();

       }

    }

}

使用methodMissing 代表toJson 方法调用。这种实现是笨的方法,使用“框架”代码侵入了domain。

以下脚本触发json的生成。

package mop.json

 

class TaskTest {

 

    static main(args) {

       def t = new Task(summary:"Mop",description:"Learn all about Mop");

       println (t.toJson());

    }

 

}

输出

{"summary":"Mop","description":"Learn all about Mop"}

聪明的方法:Groovy允许创建一个MetaClass 实例,并且会自动的将其注册到指定类中。这个注册时基于包名转换的。

//在一个包中定义一个Metaclass的实例,Groovy将会注册到一个类中
groovy.runtime.metaclass.[thePackage].[theClassName]MetaClass 

注意:该代理类的包一定按照如上规则定义。

本例是:groovy.runtime.metaclass.包名,会自动注册到Task这个domain上的。因此,Task无需继承或实现等于该代理类关联。

package groovy.runtime.metaclass.mop.json2

 

import groovy.json.JsonBuilder

 

class TaskMetaClass extends DelegatingMetaClass {

   

    TaskMetaClass(MetaClass meta) {

       super(meta);

    }

    @Override

    def invokeMethod(Object object, String method, Object[] args) {

       println(method);

       if (method == "toJson") {

           JsonBuilder b1 = new JsonBuilder(object);

           return b1.toString();

       }

       return super.invokeMethod(object, method, args);

    }

 

}

这将允许你将domain中的def methodMissing(String name,args) {这个方法去掉了。

package mop.json2

 

class Task {

    String summary;

    String description;

}

再次运行这个简短的测试脚本并且验证转换成json的工作是否有效。

package mop.json2

 

class TaskTest {

 

    static main(args) {

       def t = new Task(summary:"Mop",description:"Learn all about Mop");

       println (t.toJson());

    }

 

}

输出

toJson

{"summary":"Mop","description":"Learn all about Mop"}

原文地址:https://www.cnblogs.com/yaoyuan2/p/5719220.html