Groovy探索之MOP 十六 使用Interceptor实现简单的观察家模式

观察家模式是我们比较常用的一种模式,也是其他的一些常用模式的基础,比如MVC模式就是一种以观察家模式为基础的模式。

在Java语言中,观察家模式的实现十分的简单,就是让被观察者继承Observable类,而让观察者实现Observer接口。这些基础的用法,都在我的文字——《螳螂捕蝉、黄雀在后——从一个成语谈观察家模式》中有所谈到,在这里不再细述。

如果我们在实际的编码中有使用过观察家模式,就有可能会发现我们在Java语言中实现的观察家模式的弱点:就是,如果我们的被观察者想继承一个类的话,就会发现没有办法再继承了,因为作为一个观察者,它必须继承Observable类,而Java语言是不允许多继承的。所以这就构成了我们的观察家模式的一个最大的弱点。

在Groovy语言,我们当然也可以使用上述的方法来实现观察家模式,这种实现方式的弱点当然也被继承下来了。

在需要再次提醒的是,我们的Groovy语言拥有强大的MOP特性,有了它,我们就有可能突破我们在Java语言中所遇到的一些障碍。本篇就是要来探讨如何使用Interceptor来实现观察家模式,以及这种实现是如何突破我们前面所谈的的Java语言所实现的观察家模式的弱点的。

其实实现观察家模式的思路十分的简单:就是被观察者在做某个动作的时候,要通知一下观察者,我做了这个动作,从而使得观察者做相应的动作。这个思路的关键就在于观察者在做完某个动作后,要通知观察者。我们在学过Groovy语言的拦截器以后,就可以知道,这种通知,其实就可以使用拦截器来做。

这就是我们使用拦截器来实现观察家模式的一个简单的思路。下面以一个例子来详细说明是如何实现这个思路的。

这个例子说的是蜜蜂采花粉的事,对应于观察家模式,就是花朵在开花的时候,通知一下蜜蜂,蜜蜂就可以来采粉了。下面就是这个例子的实现。

首先是花朵类:

public class Flower{

def open()
{
println 'the flower is opening...'
}

}

在我们的实现里,Flower类的实现十分的简单,它就只管开花就行,不需要再做其他的任何事情,比如在Java语言对于观察家模式的实现中,它就需要继承Observable类,然后开完花以后,还有通知观察者——蜜蜂类。

接着来看我们的蜜蜂类:

public class Bee{

def eat()
{
println "it is bee's meal time..."
}

}

它的实现也十分的简单,只需要实现采花的动作,其他的不用管。而在我们的Java语言的观察家模式的实现中,我们的Bee类则需要实现Observer接口。

既然是使用Interceptor来实现观察家模式,那么,我们还是要实现Interceptor接口的,不然,我们怎么使用拦截器呢?

public class BeeObserver extends Bee implements Interceptor{

public Object beforeInvoke(Object object, String methodName, Object[] arguments){
// TODO Auto-generated method stub
return null
}

public Object afterInvoke(Object object, String methodName, Object[] arguments, Object result){
// TODO Auto-generated method stub
if(methodName=='open')
{
this.eat()
}
return result
}

public boolean doInvoke(){
// TODO Auto-generated method stub
return true
}

}

时间: 2024-10-19 15:49:39

Groovy探索之MOP 十六 使用Interceptor实现简单的观察家模式的相关文章

Groovy探索之MOP 十 Interceptor 二

在本系列的<Groovy探索之MOP 九 Interceptor 一>中,我们已经详细的介绍了一个简单的拦截器类的方方面面,使得我们初步有了拦截器的基础.本篇需要在前面的拦截器类的基础上,进一步用拦截器类来实现我们的AOP编程. 首先,我们在本系列的第一篇中,所拦截的方法都是固定的方法.现在,我们需要把它扩展成由拦截器类的使用者来指定被拦截的方法. 先还是给出需要被拦截的类来: class Foo { def test1() { println 'test1' } def test2() {

Groovy探索之MOP 十五 方法名的动态性

到目前为止,我们的<Groovy探索之MOP>系列已经谈到了使用ExpandoMetaClass的方方面面,但值得注意的是,我们通过ExpandoMetaClass给一个类在运行期内添加一个方法,不管是普通方法还是静态方法,我们都是添加一个确定方法名的方法.即我们添加一个方法名为A的方法,然后才能使用这个方法A. 然而,方法名的动态性,其实是我们早已接触过的事情,比如在<Groovy探索之invokeMethod方法>里,我们就可以创建形如"sortByXxxxx()&q

Groovy探索之MOP 十二 方法的调用顺序

我们知道,除了使用hook来拦截方法以外,我们还可以通过各种方式来实现方法.如,我们可以在类里直接实现方法:我们可以通过ExpandoMetaClass在运行期内添加方法:我们还可以通过ExpandoMetaClass在运行期内单独给一个对象添加方法. 所有的这些直接添加方法的途径,如果存在hook的话,都是要被hook拦截的.所以,我们可以说,系统是优先调用hook的. 而hook的调用顺序,我们在上一篇<Groovy探索之MOP 十一 运行期内覆盖invokeMethod>已经谈到过了.

Groovy探索之MOP 十四 对Java类使用Groovy语言的MOP

既然Groovy语言是Java语言的扩展,那么我们在使用Groovy语言的时候,就很难与Java语言真正脱得了干系,那怕我们是在做一个纯Groovy语言的项目,如Grails项目.我们可能在Groovy代码中会用到遗留的Java类和包:也可能是为了性能的原因,我们不得不在Groovy语言中使用到Java类:等等. 如果我们要对于Java类使用Groovy语言的MOP,比如我们想给一个Java类的对象在运行期内添加一个方法.那么我们该怎么办呢? 比如,我们有如下的一个Java类: //(Java代

Groovy探索之MOP 十三 Interceptor 三(2)

其实,阻止拦截的使用像在<Groovy探索之MOP 十三 Interceptor 三(1)>中的最后一个例子那像的使用并不多,更多的是在使用拦截器的客户那里决定是否使用拦截器.还是上一篇的那个例子: class Hello { def hello(name) { "hello,$name" } } 我们现在明确的把类中所有的方法进行拦截,拦截器如下: class AllInterceptor implements Interceptor{ Object beforeInvo

Groovy探索之MOP 十一 运行期内覆盖invokeMethod

我们很早就会使用Groovy语言的hook,即"invokeMethod"方法和其他的几个方法.我们会在一个类中实现"invokeMethod"方法,用来分派所有的或部分的在运行期内调用的该类实例的方法.这些我们在<Groovy探索之MOP 一 invokeMethod和methodMissing方法>已经详细的谈到过. 现在,我们已经深入的接触到了Groovy语言的MetaClass,更是也到处使用到了ExpandoMetaClass.我们都已经知道,

Groovy探索之MOP 九 Interceptor 一

近几年以来,AOP(面向方面的编程)得到了广泛的应用,我们把它应用到例如打印日志.权限控制等各个方面.而在实现AOP的时候,我们一般都借助于工具,如Spring AOP等等. 当然,我们借助于工具一般都用在实现系统级的AOP上,这种实现一般都要借助于配置文档来实现. 当我们需要实现较小范围的AOP的时候,比如对有限几个类的某些方法进行AOP,这时候,我们一般不希望使用工具.原因可能是第一工具不够灵活第二需要做繁琐的配置工作.这时候,我们需要自己来实现AOP的方方面面. Java语言一般来说,有两

Groovy探索之MOP 一 invokeMethod和methodMissing方法

终于要谈到Groovy语言的MOP特性了,我在前面的章节中零星的谈到了它,却始终没有系统的来谈到它.这是因为Groovy语言的MOP特性实在是太灵活了,比如本章节要谈到的"invokeMethod"和"methodMissing"方法,它们的功能有很大的相似之处,而区别却相当的微妙.但是,不管怎么样,Groovy语言的MOP编程都是我们必须掌握的.而这个系列我没有计划多少个部分谈完,跟<Groovy探索之闭包>系列一样,探索一部分说一部分. 本节要谈到的

Groovy探索之MOP 七 运行期内的方法和属性分析

在Groovy语言里,运行期内的方法和属性分析有三种方式,它们分别是: 第一, 继承自Java语言的反射方式. 第二, 使用"respondsTo"和"hasProperty"方法. 第三, 使用"hasMetaMethod"和"hasMetaProperty"方法. 以上三种方法都能在运行期内分析某个方法或属性是否存在,相信我们看到这里,一定会想,它们之间是否有什么区别呢? 漫谈这三种运行期内的方法和属性分析方式以及它们之间