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
}
}
这个实现我就不多说,它首先继承了Bee类,然后实现了Interceptor接口,就是一个简单的拦截器实现。在“afterInvoke”方法里判断一下是否是“open”方法,代表的是花开动作,如果是的话,就通知Bee类,该采花了,即调用了Bee类对象的“eat”方法。
最后,我们来使用这个拦截器来实现观察家模式:
def proxy= ProxyMetaClass.getInstance( Flower )
def bee = new BeeObserver()
proxy.interceptor= bee
proxy.use{
def flower = new Flower()
flower.open()
}
这种实现也十分的简单,跟普通的拦截器的使用一模一样,在这里,我们就不多说了。上面代码的运行结果为:
the flower is opening...
it is bee's meal time...
果然是十分轻松的实现了我们的观察家模式。
由于我们的Flower类十分的干净,没有任何的因为要实现观察家模式所强加的代码,因此,它可以再继承任何的父类。对于我们的观察者——Bee类,也是同样的道理。
关于这一点,在这里只是点到为止,不再多说,因为都十分的简单。
倒是对于我们的观察者,则可以有进一步的简化的可能,因为我们的观察者只需要实现“afterInvoke”方法,其他的Interceptor接口的两个方法则不必管它。
所以,我们可以进一步抽象一下观察者:
abstract public class BaseObserver 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
return true
}
abstract public boolean doInvoke();
}
现在,我们的观察者,则只需要继承“BaseObserver”类即可。当然了,如果我们的观察者类需要继承其他的父类,则无需做此抽象。一切凭你的现实需要。
以上,我们就使用Interceptor来实现了一个简单的观察家模式。当然了,观察家模式还有比上面所讲到的更为复杂的,这就是我们另外一个主题所要谈到的内容,在这里就不多说了。