首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

MOP——方法注入(1)

MOP——方法注入(1)

方法拦截和方法注入的区别

拦截:侧重对于已有的方法的调用进行拦截
注入:对一个已有的类添加新方法,以拓展该类的功能。

eg:Java 中提供了 String 的类,如果我们想扩展该类,为其提供一个字符串加密方法。在 Java 中,最常见的做法是提供一个接口,内有 encrypt() 方法,让目标类实现该接口;或者继承该类,然后添加一个 encrypt() 方法。但是这里存在的问题是:我们未必可以修改想要扩展的类,就像 String,还是 final 的,只能用,不能改。

不过使用 Groovy,就可以方便的为任何类扩展方法,同时在使用起来,给人的感觉就好像注入的类是该类本身就有的。

MOP 的注入有四种实现方式:

    分类(Category)
    ExpandoMetaClass
    Minxin
    trait

使用分类进行方法注入

第一次接触 Category 的概念是在学习 Objective-C 的时候,只要自定义一个和目标类相同的类,然后在自定义类中添加方法,那么在方法调用时,会先从自定义的类中查找,找不到后再去原本的类中查找。这样一来不仅可以扩展类的方法,同时还可以覆盖原有类的方法。Objective-C 中 Category 感觉是最优雅的方式了。而 Groovy 中的 Category 就逊色的多,接下来看一下 Groovy 中 Category 的使用方法,这里以向 String 中添加一个 encrypt 方法为例。

    class StringUtils {
        def static encrypt(String self) {
            byte[] arr = self.bytes;
            for (int i = 0; i < arr.length; i++) {
                arr[i] = (127 - arr[i])
            }
            return new String(arr)
        }
     
     
    }
     
    class IntegerUtils{
        def static add(Integer a, int b) {
            a + b
        }
    }
     
    use(StringUtils,IntegerUtils) {
        String str = "hello"
        s = str.encrypt()
        println 1.add(2)
    }

这里先定义了一个的类,其中定义了一个方法 encrypt(),要想要该类成为 String 的分类,需要注意以下几点:

    其内部定义的方法必须为 static
    方法的第一个参数必须定位为目标类的类型(eg:这里定义的 String,当然你可以不写类型,这样就有可能让多个类都是用该方法了),如果该方法还需要参数,那么就从第二个形参开始声明。
    第一个参数如果声明类型,必须为包装类的类型,eg:如果我们想为整数提供方法,即使用到了 1.add(2) 这样的调用方式,但这是 groovy 提供的语法糖,其本质任为 Integer,因此在定义分类的方法时,第一个参数必须是包装类型

在使用时,其必须在 use 所定义的代码块中,出了代码块就无法使用分类中的方法了,否则报找不到方法的错误。在 use 后面必须注明要注入的方法所在的类,eg:use(StringUtils),use 中可以注入多个类,如果多个分类中有重复的方法定义,那么以最后一个分类中方法为准。
返回列表