看spring的ioc,感觉很点意思,于是自己写了一个Spring之FileSystemXmlApplicationContext的模拟类,贴出来请大家斧正.
1.功能说明:关于订单,折扣,价格
订单是货物的订单,主要货物有计算机,文具,纸张三类,还有其它一些物件.每种货物都有不同的折扣比例,从单价中扣除折扣比例后就是进货时的真实价格.
2.Spring之Ioc实现
这里就不赘述了,详情请见帖子
http://www.blogjava.net/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   
感悟:自己做过一遍后,觉得很多框架并非想像中那样神秘高深,只要肯动脑筋,愿意动手,我们有机会站在时代的风口浪尖上,: ).