2014年8月2日

股市自動交易系統(半完成品) - JavaATS程式架構 - Config Manager

這篇要來描述Config Manager的部份,在JavaATS的架構圖如下藍色框框部份:
ConfigManager是屬於比較單純的部份,
它主要功能就是XML的Parser,負責將XML資訊讀出成變數。

ConfigManager功能與呼叫方式:
JavaATS會在一開始時透過ConfigManager載入所有變數,
之後JavaATS所有變數的取得,都是透過ConfigManager。

例如:
xml設定檔檔名為:configs.xml

則在JavaATS一開始時,會呼叫:
CONFIG = new ConfigManager(configs.xml);

之後所有設定都會讀入CONFIG當中。

例如要取得MySQL設定的IP,如下:
String ip = CONFIG.getMySQLIP();

ConfigManager程式結構:
Java的XML Parser有2套,是:

  • DOM XML Parser
  • SAX XML Parser
DOM的優點是程式碼比較容易結構化,缺點是操作比較麻煩,
SAX的優點是,操作單純,但程式碼比較不好結構化。

在寫這部份時,正好就學習SAX XML Parser使用方式,
因此,JavaATS的XML Parser,原則上都是用SAX XML Parser。

SAX XML Parser:
這裡不得不稍微提下Java SAX XML Parser的使用方式,
Java SAX XML Parser程式碼結構大致如下:
File f = new File(configs.xml);
DefaultHandler XMLHandler = new DefaultHandler() {}

SAXParserFactory spf = SAXParserFactory.newInstance();
SAXParser saxParser = spf.newSAXParser();
saxParser.parse(f, XMLHandler);
原則上,SAXParser的設計是:

  1. 先建立並初始化SAXParserFactory物件
  2. 從SAXParserFactory取出Parser
  3. 設定Parser的XML檔案和Handler

上述的程式碼結構,就是先建立出XML的File和Parser Handler,
然後按設計,建立並設定到Parser內,就會開始Parse XML了。

Handler的實做包括:
public void startElement(String uri, String localName,String qName, Attributes attributes)
public void endElement(String uri, String localName, String qName)
public void characters(char[] ch, int start, int length)

SAX Parser會從頭一行一行讀XML,
當讀到StartElement時,就會跳入startElement()的Handler function,
要開始讀內容時,就會跳入characters()的Handler function,
當讀到EndElement時,就會跳入endElement()。

例如:
<Config>
HelloWorld
</Config>
當讀到<Config>時,就會跳入startElement(),
在startElement()內,就會取得Config這個標籤名稱是開頭。

當讀到Hello World時,就會跳入characters(),
在characters()內,就可以取得Hello World。

當讀到</Config>時,就會跳入endElement(),
在endElement()內,就會取得Config這個標籤名稱是結尾。

ConfigManager程式碼結構:
ConfigManager程式碼依循SAX設計,
在Handler內,將Config XML的載入透過startElement()、characters()、endElement()分開。

原則上,每個項目的參數,都會包括:

  • 變數Element:用在startElement()時,標記目前要讀取的變數,在endElement()時,標記變數已讀取完畢
  • 變數本身:用在characters()時,實際讀出並紀錄變數

例如:
MySQL的IP資訊

SQLElement:紀錄是否要讀取SQL資訊
MySQLIP:紀錄MySQL的IP

在startElement()時,當標籤是SQL,就將SQLElement設為true,
在characters()時,檢查到SQLElement == true,就讀取標籤內容,並設定到MySQLIP。

程式碼大致如下:
public void startElement()
{
  if(qName.equals("SQLElement"))
    SQLElement = true;
}
public void characters()
{
  if(SQLElement == true)
    MySQLIP = new String(ch, start, length);
}

public void endElement()
{
  if(qName.equals("SQLElement"))
    SQLElement = false;
}

沒有留言: