看spring的ioc,感覺很點意思,于是自己寫了一個Spring之FileSystemXmlApplicationContext的模擬類,貼出來請大家斧正.
1.功能說明:關于訂單,折扣,價格
訂單是貨物的訂單,主要貨物有計算機,文具,紙張三類,還有其它一些物件.每種貨物都有不同的折扣比例,從單價中扣除折扣比例后就是進貨時的真實價格.
2.Spring之Ioc實現
這里就不贅述了,詳情請見帖子
http://www.tkk7.com/sitinspring/archive/2007/06/06/122326.html
3.模擬實現
// 折扣接口
public interface Discount{
public float getDiscount();
public void setDiscount(float discount);
}
// 計算機折扣類
public class ComputerDiscount implements Discount{
private float discount=0.0f;
public float getDiscount(){
return discount;
}
public void setDiscount(float discount){
this.discount=discount;
}
}
// 文具折扣類
public class StationaryDiscount implements Discount{
private float discount=0.0f;
public float getDiscount(){
return discount;
}
public void setDiscount(float discount){
this.discount=discount;
}
}
// 紙張折扣類
public class PaperDiscount implements Discount{
private float discount=0.0f;
public float getDiscount(){
return discount;
}
public void setDiscount(float discount){
this.discount=discount;
}
}
// 其它折扣類
public class OtherDiscount implements Discount{
private float discount=0.0f;
public float getDiscount(){
return discount;
}
public void setDiscount(float discount){
this.discount=discount;
}
}
// 訂單類
public class Order{
public static final String Type_Computer="Computer";
public static final String Type_Stationary="Stationary";
public static final String Type_Paper="Paper";
private String type;
private float price;
public Order(float price,String type){
this.price=price;
this.type=type;
}
public Order(){
this(100.0f,"Other");
}
// 調用模擬類的地方,看看調用過程和Spring很相似吧
public float getPrice() {
MockContext ctx = new MockContext("bean.xml");
Discount discount = null;
discount = (Discount) ctx.getBean(this.type);
return price * (1.0f - discount.getDiscount());
}
}
// Spring之FileSystemXmlApplicationContext的模擬類
/**
* Spring之FileSystemXmlApplicationContext的模擬類
*
* @author junglesong
*
*/
public class MockContext {
Document doc = null;// 用于解析Bean配置文件的Xml Document
Element root = null;// Bean文件的根節點
/**
* 構造函數,用于初始化doc和root
* @param beanFileName
*/
public MockContext(String beanFileName) {
SAXBuilder buider = new SAXBuilder();
try {
doc = buider.build(new File(beanFileName));
root = doc.getRootElement();
} catch (Exception ex) {
ex.printStackTrace();
}
}
/**
* 根據beanId創建類并調用規定的方法
*
* @param beanId
* @return
*/
public Object getBean(String beanId) {
Object obj=null;
try {
Element beanElm =getSubElm(root,"id",beanId);
if(beanElm!=null){
String className=beanElm.getAttribute("class").getValue();
Class cls=Class.forName(className);
// 由類得到類實例
obj=cls.newInstance();
List ls=beanElm.getChildren();
for(Iterator it=ls.iterator();it.hasNext();){
Element elm=(Element)it.next();
String methodName=elm.getAttributeValue("name");
String methodValue=(String)elm.getChildText("value");
// 取得類方法
Method method = cls.getMethod(getSetterMethod(methodName), new Class[] {getClassByValue(methodValue)});
// 建立數組
Object params[]=getParamsByValue(methodValue);
// 調用類方法
method.invoke(obj,params);
}
}
} catch (Exception ex) {
ex.printStackTrace();
}
return obj;
}
/**
* 由參數的值得到參數的類型,目前可處理浮點數和字符串兩種情況
*
* @param value
* @return
*/
private Class getClassByValue(String value){
Class cls=String.class;
try{
Float.parseFloat(value);
cls=float.class;
}
catch(Exception ex){
ex.printStackTrace();
}
return cls;
}
/**
* 由參數的值得到包含參數的數組,目前可處理浮點數和字符串兩種情況
*
* @param value
* @return
*/
private Object[] getParamsByValue(String value){
Object[] params=new Object[1];
try{
Float.parseFloat(value);
params[0]=new Float(Float.parseFloat(value));
}
catch(Exception ex){
ex.printStackTrace();
params[0]=new String(value);
}
return params;
}
/**
* 取得root下屬性為subElmAttr,值等于subElmValue的節點
*
* @param root
* @param subElmAttr
* @param subElmValue
* @return
*/
private Element getSubElm(Element root,String subElmAttr,String subElmValue){
Element rtv=null;
List ls=root.getChildren();
for(Iterator it=ls.iterator();it.hasNext();){
Element elm=(Element)it.next();
if(elm.getAttribute(subElmAttr).getValue().equals(subElmValue)){
rtv=elm;
break;
}
}
return rtv;
}
/**
* 取得setter方法
*
* @param methodName
* @return
*/
private String getSetterMethod(String methodName){
return "set"+methodName.substring(0,1).toUpperCase()+methodName.substring(1,methodName.length());
}
}
調用的代碼如下:
java 代碼
Order computerOrder=new Order(100.0f,Order.Type_Computer);
System.out.println("computerOrder's price is \t"+computerOrder.getPrice());
Order stationaryOrder=new Order(100.0f,Order.Type_Stationary);
System.out.println("stationaryOrder's price is \t"+stationaryOrder.getPrice());
Order paperOrder=new Order(100.0f,Order.Type_Paper);
System.out.println("paperOrder's price is \t\t"+paperOrder.getPrice());
Order otherOrder=new Order();
System.out.println("otherOrder's price is \t\t"+otherOrder.getPrice());
輸出效果和使用Spring是一樣的,速度慢了些,但可以優化:
java 代碼
computerOrder's price is 70.0
stationaryOrder's price is 80.0
paperOrder's price is 90.0
otherOrder's price is 95.0
感悟:自己做過一遍后,覺得很多框架并非想像中那樣神秘高深,只要肯動腦筋,愿意動手,我們有機會站在時代的風口浪尖上,: ).