看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
感悟:自己做过一遍后,觉得很多框架并非想像中那样神秘高深,只要肯动脑筋,愿意动手,我们有机会站在时代的风口浪尖上,: ).