原文連結: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降低了二次開發的難度。