原文链接:http://www.hechunchen.info/?p=15
我们知道openfire插件开发主要有3种方式注册方式:1)IQHandler(IQ handlers respond to IQ packets with a particular element name and namespace),2)Interceptor(PacketInterceptor to receive all packets being send through the system and optionally reject them),3)Component(Components receive all packets addressed to a particular sub-domain)。
今天来讲IQHandler涉及到的一种设计模式——模板方法(Template Method)模式。
模板方法最标志性的特点,是,他需要一个抽象类。在java设计模式中,其实很少用到抽象类,更多地还是用到接口。
我们如果要做自己的IQ包处理,可以自定义类如TestTemplateMethodHandler:class TestTemplateMethodHandler extends IQHandler,然后在public IQHandlerInfo getInfo()方法中写上自己想要注册的元素名及命名空间,在public IQ handlerIQ(IQ packet)方法中写上自己想要对丢进来的IQ包做什么样的处理(注意IQ包是基于问答形式的,所以应该有IQ包的reply)。
给一段示例代码:
1 import org.jivesoftware.openfire.IQHandlerInfo;
2 import org.jivesoftware.openfire.auth.UnauthorizedException;
3 import org.jivesoftware.openfire.handler.IQHandler;
4 import org.xmpp.packet.IQ;
5
6 public class TestTemplateMethodHandler extends IQHandler
7 {
8 private IQHandlerInfo info;
9
10 public TestTemplateMethodHandler()
11 {
12 super("TestTemplateMethodHandler");
13 info = new IQHandlerInfo("query", "http://hechunchen.info/querytest");
14 }
15 @Override
16 public IQHandlerInfo getInfo()
17 {
18 // TODO Auto-generated method stub
19 return info;
20 }
21
22 @Override
23 public IQ handleIQ(IQ packet) throws UnauthorizedException
24 {
25 // TODO Auto-generated method stub
26 IQ reply = IQ.createResultIQ(packet);
27 System.out.println("iq from:" + reply.getFrom());
28 System.out.println("iq to:" + reply.getTo());
29 return reply;
30 }
31 }
需要注意的是:父类的其他方法是一定会调用它abstract的方法。不然,子类写的方法(算法的小细节)根本没有被用到。比如handlerIQ方法就在IQHandler中的void process(Packet packet)调用到。
总结来讲,openfire用Template Method这个模式非常到位。模板方法模式非常适合于可能会做二次开发的系统。我们在父类中定义好了算法的大框架,将一些小细节的确定可以推迟到子类中去实现。就像IQHandler已经写好了算法大框架,我们二次开发者只需要extends IQHandler之后,自己写上2个方法的实现,处理丢过来的IQ包。我们完全不用管IQ包是怎么路由到我们这里来的。显然,Template Method降低了二次开发的难度。