獲取xml配置資料
1 詳細功能
1.1 詳細功能
為了實現theme的即配即用,規定theme的配置使用xml檔案,框架的配置和模組的配置的provider都可以由使用者指定,可以在執行時傳入框架配置的provider,然後在 框架配置裡面指定了模組配置的provider。
因此本章講述獲取預設的xml方式配置的資料。
1.2 功能邊界
只是負責配置檔案為xml時候的讀取、解析並獲取xml中的配置資料。其實就是實現前面橋接模式的抽象部分的介面。
2 內部實現
2.1 加入直譯器模式
2.1.1面臨的問題
自己解析xml,本來也沒有什麼特別困難的,但是問題就在於,如果xml檔案的格式發生了變化,那麼讀取配置檔案的程式就需要做出相應的變更,嚴重的時候,幾乎相當於完全重寫程式。
那麼怎麼解決當xml的結構發生改變過後,能夠很方便的獲取相應元素、或者是屬性的值,而不用再去修改解析xml的程式呢?
2.1.2用直譯器模式來解決
1)模式定義:
給定乙個語言,定義它的文法的一種表示,並定義乙個直譯器,這個直譯器使用該表示來解釋語言中的句子。
2)模式本質:
直譯器模式的本質:分離實現,解釋執行。
3)基礎知識:
(1)直譯器模式使用直譯器物件來表示和處理相應的語法規則,一般乙個直譯器處理一條語法規則。
(2)直譯器模式沒有定義誰來構建抽象語法樹,把這個工作交給了客戶端處理
(3)使用直譯器模式的時候,應該先定義好相應的語法規則,並根據規則制定直譯器的語法樹;然後客戶端在呼叫直譯器進行解釋操作的時候,需要自行構建符合語法規則要求的語法樹;而直譯器模式只是負責解釋並執行。
(4)從實質上看,直譯器模式的思路仍然是分離、封裝、簡化,跟很多模式是一樣的。
4)常見應用場景:
語法較為簡單的自定義表示式解析,比如自定義xml文件的解析,文件結構不要太複雜,那不適合使用直譯器模式。
直譯器模式的基本實現,沿用了《研磨設計模式》一書的直譯器模式一章中最後實現的通用解析程式,由於篇幅關係,這裡就不會那麼詳細的講述實現的細節,這裡更關心實現的思路,比較高層一點。因此更多的細節請檢視源**或是《研磨設計模式》一書的直譯器模式一章的內容。
很明顯,使用直譯器模式來解決這個問題是乙個很好的思路。
設計乙個簡單的表示式規則,然後通過直譯器模式來進行解析執行,從而獲取到xml中的值。
約定簡單的語法規則如下:
1:為表示式設計簡單的文法
為了通用,用root表示根元素,a、b、c、d等來代表元素,乙個簡單的xml如下:
<?xml version="1.0" encoding="utf-8"?>12345 d1 d2 d3 d4f1 f2 約定表示式的文法如下:
ø獲取單個元素的值:從根元素開始,一直到想要獲取值的元素,元素中間用「/」分隔,根元素前不加「/」。比如表示式「root/a/b/c」就表示獲取根元素下、a元素下、b元素下的c元素的值
ø獲取單個元素的屬性的值:要獲取值的屬性一定是表示式的最後乙個元素的屬性,在最後乙個元素後面新增「.」然後再加上屬性的名稱。比如表示式「root/a/b/c.name」就表示獲取根元素下、a元素下、b元素下、c元素的name屬性的值
ø獲取相同元素名稱的值,當然是多個:要獲取值的元素一定是表示式的最後乙個元素,在最後乙個元素後面新增「」。比
如表示式
「roo
t/a/
b/
d」。比如表示式「root/a/b/d
」。比如表達
式「ro
ot/a
/b/d
」就表示獲取根元素下、a元素下、b元素下的多個d元素的值的集合
ø獲取相同元素名稱的屬性的值,當然也是多個:要獲取屬性值的元素一定是表示式的最後乙個元素,在最後乙個元素後面新增「」,然
後在後面
新增「.
」然後再
加上屬性
的名稱,
在屬性名
稱後面也
新增
「」,然後在後面新增「.」然後再加上屬性的名稱,在屬性名稱後面也新增「
」,然後在後
面新增「
.」然後
再加上屬
性的名稱
,在屬性
名稱後面
也新增「
」。比如表示式「root/a/b/d.id
.id.i
d」就表示獲取根元素下、a元素下、b元素下的多個d元素的id屬性的值的集合
ø如果要獲取某個需要區分的元素下面的值,那麼對於判斷使用這樣的語法:[屬性名=值],屬性名和值都不需要加引號,比如:要想獲取id=」e1」的e元素下面的f元素的值,就是用這樣的表示式:root/a/e$[id=e1]/f。
2:核心**示例
(1)先來看看readxmlexpression的示例,示例**如下:
/**
(2)看看以單個元素作為中間元素的實現,要注意跟以前的實現相比,新增了對條件的判斷,示例**如下:
/** public string interpret(context c) else
}list templist = new arraylist();
//判斷是否滿足條件,滿足條件才放入
if(noweles.size()>0 && c.judgecondition(noweles.get(0), condition))
}
//迴圈呼叫子元素的interpret方法
string ss = null;
for(readxmlexpression tempele : eles)
return ss;
}
public void seteles(list eles)
public list geteles()
}(3)看看以多個元素作為中間元素的實現,要注意跟以前的實現相比,新增了對條件的判斷,示例**如下:
/**public booleanaddele(readxmlexpression ele)
public booleanremoveele(readxmlexpression ele)
public voidseteles(list eles)
publiclist geteles()
}(4)看看以單個元素作為終結符元素的實現,要注意跟以前的實現相比,新增了對條件的判斷,示例**如下:
/** public string interpret(context c) else
//判斷是否滿足條件
if(!c.judgecondition(ele,condition))
//然後需要去獲取這個元素的值
string ss = new string[1];
if(ele.getfirstchild()!=null)else
return ss;}}
(5)看看以多個元素作為終結符元素的實現,要注意跟以前的實現相比,新增了對條件的判斷,示例**如下:
/**(6)看看以單個屬性作為終結符元素的實現,示例**如下:
/** public string interpret(context c)
}(7)看看以多個屬性作為終結符元素的實現,示例**如下:
/** public string interpret(context c)
設計模式綜合總結
定義 動態地給物件新增一些額外的職責,就像是在牆上刷油漆,使用decorator模式相比生成子類方式達到功能的擴充顯得更為靈活.為什麼使用 我們通常使用繼承來實現功能的擴充套件,如果這些需要擴充套件的功能種類繁多,那麼勢必生成很多子類,增加系統的複雜性 同時,使用繼承實現功能拓展,我們必須可以預見這...
實戰筆記 設計模式
一 各種設計模式詳解 二 開發常用設計模式 最佳例項 1.工廠模式 通過工廠方法建立指定型別的物件,常與其他設計模式配合使用 最佳例項 spring bean factory 2.策略模式 封裝不同類的處理邏輯為策略,配置工廠模式在不同入參情況返回不同策略類 相對固定的分類處理 更加優雅易擴充套件 ...
常用設計模式 策略模式實戰
什麼是策略模式?常用設計模式 策略模式 場景 假設有乙個支付的業務場景,不同 的訂單要做不同的處理 下面是普通的寫法 override public string order order order else if order.getsource equals ordersourceenum.wec...