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"} |