一.背景
在現在的網站中,存取的管道是越來越多了,技術也是越來越先進,WAP, SMS,EMAIL, 傳統的Web, Socket等等,如果連資料庫和LDAP也算是存取的話,那在設計之中需要擴充的空間要做到很好很好,才保證在新增新的管道情況下不需要更多的修改程式碼甚至不改程式碼的情況。但可能嗎?我想也不可能,但有什麼方式可以更好的解決這種多渠道接入的框架的完美性呢?
二.構架

## 【圖一】
如圖一所顯示,在現有的所有接入都已經使用上的時候,設計者看的都眼花繚亂了,如果是為了湊份子,那這些程式怎麼寫都可以,而且也肯定可以實現,但維護起來就會比較痛苦,還是回到那個問題,怎麼可以實現更完美呢?如圖二顯示:
##【圖二】
圖二看起來像八爪的章魚,章魚腿分別連接所有的接入渠道,進行連接所有這些渠道的核心就是這個章魚的頭xmlRouter, Router在此的作用是溝通所有管道,實現資料的路由,爭強系統在架構上的擴展性和靈活性,好處會很多很多。稱為XMLRouter是因為如果不使用XML這種靈活而又規範的語言來做為數據傳輸的媒介,那Router的工作量也同樣會成倍的增加,定義好XML的規範後將為以後的擴展帶來很多好處。
三.思想與模式
XMLRouter的最初想法來自於電腦的主機板和之中的Builder Pattern, 電腦主機板的PCI 插槽定義了PCI的規範,只要你生產的卡符合PCI標準,那你插入到這個主板上就可以工作, 至於裡面是怎麼工作的則是已經封裝好了. Builder Pattern則是提出將復雜的構建分離開來, 一步一步的進行實現.XMLRouter是將這些複雜的管道分離開來,一個個的進行表現.
Services思想:為了能和Router進行溝通,在這些渠道接入時必須定義統一的接口,這裡成為Services,只要符合Services規範的程式就可以接入Router並進行資料的路由.
Factory模式和Composite模式
XMLRouter在實際的設計中將採用Factory模式產生,Router由RouterFactory生產, 在投入使用時將放置於隊列中,傳遞數據和接收數據以及返回數據都從隊列中取相應的Router來調用,應用了Composite的模式.
四.XML配置文件
XML檔案對於Router之中的使用分為兩個部分, 第一個是Router的配置,如:
以下是引用片段:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | <?xml version= "1.0" ?>
<services>
<!-- database Service -->
<service name= "database" type= "database" class = "com.web.service.DBService" >
<connector
driver= "com.microsoft.jdbc.sqlserver.SQLServerDriver"
url= "jdbc:microsoft:sqlserver://192.168.0.179:1433" user= "test"
passwd= "test" />
</service>
<!-- Web Service-->
<service name= "web" type= "web" class = "com.web.service.WebService" >
<connector />
</service>
……
</services>
|
登入後複製
這是Router的設定檔, service節點代表需要存取的頻道, service節點包含connector子節點, 子節點的設定依type來區分, 如果是database則包含url, user, passwd,driver等屬性, 如果是socket則包含port, maxthread等屬性, 屬性值可以根據自己的定義來配置.
另一種XML檔案則是XML交易資料檔,用於在所有的services中傳遞資料,每個Services自己包涵一個對應的XML檔案,比如webtrans.xml格式如下:
以下是引用片段:
1 2 3 4 5 6 7 8 9 | <?xml version= "1.0" ?>
<transaction>
<trans name= "addDoc" service= "database" method= "insert" >
<PRoperty name= "createtime" type= "timestamp" />
<property name= "creatorid" type= "long" />
<property name= "doctypeid" type= "int" />
<property name= "docstatusid" type= "int" />
</trans>
</transaction>
|
登入後複製
對應的dbtrans.xml格式如下
##以下是引用片段:
1 2 3 4 5 6 7 8 9 | <trans name= "addDoc" table= "TDOC_DOCS" method= "insert" >
<primarykey name= "docid" />
<set>
<property name= "createtime" type= "timestamp" />
<property name= "creatorid" type= "long" />
<property name= "doctypeid" type= "int" />
<property name= "docstatusid" type= "int" />
</set>
</trans>
|
登入後複製
其餘XML則可依這樣的規則來客製化
五.技術實作
RouterFactory
#以下是引用片段:
1 2 3 | package com.web.router;
import com.web.platform.Exception.RouterException;
import java.util.java/util/Hashtable.java.html " target=" _blank">Hashtable;
|
登入後複製
以下是引用片段:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 |
public class RouterFactory
{
private static java/util/Hashtable.java.html " target=" _blank">Hashtable QueuePairFront = null;
private static java/util/Hashtable.java.html " target=" _blank">Hashtable QueuePairBack = null;
private static java/util/Hashtable.java.html " target=" _blank">Hashtable QueueRouter = null;
public static XMLRouter instance = null;
public static RouterDefine routerdefine = null;
public static long routeIndex = 0;
public RouterFactory()
{
}
public static void initFactory() throws java/lang/Exception.java.html " target=" _blank">Exception
{
QueuePairFront = new java/util/Hashtable.java.html " target=" _blank">Hashtable();
QueuePairBack = new java/util/Hashtable.java.html " target=" _blank">Hashtable();
QueueRouter = new java/util/Hashtable.java.html " target=" _blank">Hashtable();
initRouteDefine();
}
private static void initRouteDefine() throws java/lang/Exception.java.html " target=" _blank">Exception
{
if ( routerdefine == null )
routerdefine = new RouterDefine();
routerdefine.loadRouterDef();
}
public static XMLRouter getInstance(long index) throws RouterException
{
return (XMLRouter)QueueRouter.get( new java/lang/Long.java.html " target=" _blank">Long(index));
}
public static XMLRouter popInstance() throws RouterException
{
routeIndex ++;
instance = new XMLRouter(routeIndex);
setDefine( instance );
QueueRouter.put( new java/lang/Long.java.html " target=" _blank">Long(routeIndex), instance);
return instance;
}
private static void freeResource() throws java/lang/Exception.java.html " target=" _blank">Exception
{
QueuePairFront.clear();
QueuePairBack.clear();
QueueRouter.clear();
QueuePairFront = QueuePairBack = QueueRouter = null;
}
public static void removeInstance(XMLRouter instance) throws java/lang/Exception.java.html " target=" _blank">Exception
{
instance.clear();
QueueRouter.remove( new java/lang/Long.java.html " target=" _blank">Long(instance.getIndex() ) ) ;
}
public static boolean isNull()
{
……
return false;
}
}
|
登入後複製
# XMLRouter
以下是引用片段:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 | package com.web.router;
import com.web.platform.Exception.RouterException;
import com.web.common.*;
import java.util.*;
import java.lang.reflect.java/lang/reflect/Method.java.html " target=" _blank">Method;
import java.lang.reflect.java/lang/reflect/Constructor.java.html " target=" _blank">Constructor;
public class XMLRouter
{
private static java/util/Hashtable.java.html " target=" _blank">Hashtable QueuePairFront = null;
private static java/util/Hashtable.java.html " target=" _blank">Hashtable QueuePairBack = null;
private long routeIndex = 0;
private RouterDefine define = null;
private java/lang/String.java.html " target=" _blank ">String action = " ";
private java/lang/String.java.html " target=" _blank ">String classname = " ";
public XMLRouter(long index)
{
routeIndex = index;
}
public void routing(Env env) throws RouterException, java/lang/Exception.java.html " target=" _blank">Exception
{
if ( action.equalsIgnoreCase( RouterConstant.CFG_FUNC_ROUTETO ) )
{
……
}
else if ( action.equalsIgnoreCase( RouterConstant.CFG_FUNC_ROUTEBACK ) )
{
……
}
else
throw new RouterException( "Set Router action error." );
}
public long getIndex()
{
return routeIndex;
}
public void clear() throws RouterException
{
QueuePairFront.remove( new java/lang/Long.java.html " target=" _blank">Long(routeIndex));
QueuePairBack.remove( new java/lang/Long.java.html " target=" _blank">Long(routeIndex));
java/lang/System.java.html " target=" _blank">System.runFinalization();
}
public void setDefine(RouterDefine def) throws RouterException
{
define = def;
}
public void setAction( java/lang/String.java.html " target=" _blank">String actionName )
{
action = actionName;
}
}
|
登入後複製
Service類別
以下是引用片段:
###
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 | package com.web.common;
import com.web.platform.Exception.RouterException;
public abstract class RouteService
{
public RouteService()
{
}
public abstract void routeto(Env env) throws RouterException;
public abstract void routeback(Env env) throws RouterException;
public abstract void routeaccept(Env env) throws RouterException;
public abstract void routing() throws RouterException;
|
登入後複製
# ########### 接下來則需要實作所有的Services的類別了,這裡就不做介紹了.###### 六.說明###### 這個Router到目前為止只能實現同步的交易, 暫時不支援異步的交易,但是由於對Router使用了Composite的模式設計的,實現異步交易也是可以擴展的,這裡不做詳細分析.###### 以上就是如何使用XML實現多通路接取網站的架構的內容,更多相關內容請關注PHP中文網(www.php.cn)! ################