现在的位置: 首页 > 综合 > 正文

Spring的意义:以一个具体场景说明spring IOC的意义

2014年09月05日 ⁄ 综合 ⁄ 共 3767字 ⁄ 字号 评论关闭

我们知道spring是一个非常通用的框架,几乎所有java企业开发的用户都用到了spring,这是为什么呢?spring有什么意义呢?

我们知道软件开发中有个非常著名的原则,叫开闭原则,即对扩展开发,而对修改关闭。spring的意义就在于使用它可以很方便的开发出符合开闭原则的软件。

下面我们通过实例说明。假定我们有这么一个场景,计算打折,我们知道打折有很多不同的算法,而有可能会需要不停的加入新的打折算法。这里对应到开闭元则中就是对添加新的打折算法是开发的,而对于之前的代码修改是要关闭的。

打折算法的计算其实是经典的策略模式,我们可以把计算打折作为一种策略类抽象出来。我们首先定义计算打折逻辑的接口,其代码如下:

package cn.outofmemory.spring;

public interface DiscountLogic {
	double calcDiscount(double price);
}

这个接口只有一个方法calcDiscount(price),接受一个原始价格,计算出打折之后的价格。

我们实现了两种不同的打折,算法,一种是按配置好的折扣打折,另一种是0折扣,就是不打折,两种算法的实现类如下:

package cn.outofmemory.spring;

public class SimpleDiscountLogic implements DiscountLogic {
	private int discountRate;
	public int getDiscountRate() {
		return discountRate;
	}
	public void setDiscountRate(int discountRate) {
		this.discountRate = discountRate;
	}

	@Override
	public double calcDiscount(double price) {
		return price * this.discountRate / 100;
	}

}
package cn.outofmemory.spring;

public class LazyDiscountLogic implements DiscountLogic {
	@Override
	public double calcDiscount(double price) {
		return price;
	}

}

假定我们的应用中就是这两个打折算法的实现,有了打折算法,还需要具体计算打折的类Discount,这个类有一个打折逻辑discountLogic的属性,可以通过属性指定不同的打折算法,他的实现如下。

package cn.outofmemory.spring;

public class Discount {
	private DiscountLogic discountLogic;

	public DiscountLogic getDiscountLogic() {
		return discountLogic;
	}

	public void setDiscountLogic(DiscountLogic discountLogic) {
		this.discountLogic = discountLogic;
	}
	
	public double getDiscountPrice(double price) {
		return this.discountLogic.calcDiscount(price);
	}
}

这样涉及到的类就都就绪了,我们看下如何在spring的配置文件中配置这些类,以便方便的切换不同的打折算法。spring配置文件的内容如下:

<?xml version="1.0" encoding="UTF-8"?> 
<beans xmlns="http://www.springframework.org/schema/beans" 
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
 xsi:schemaLocation="http://www.springframework.org/schema/beans 
 http://www.springframework.org/schema/beans/spring-beans.xsd"> 
 <bean class="cn.outofmemory.spring.SimpleDiscountLogic" id="simple"> 
 <property name="discountRate" value="80" /> 
 </bean> 
 
 <bean class="cn.outofmemory.spring.Discount"> 
 <property name="discountLogic" ref="simple" /> 
 </bean> 
 
</beans>

 在spring的配置文件中,我们定义了两个bean,一个是SimpleDiscountLogic的simple实例;另一个bean是Discount类,他的属性discountLogic引用了simple。

我们看下如何使用,App类代码:

package cn.outofmemory.spring;


import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class App {
	public static void main(String[] args) {
		ApplicationContext appContext = new ClassPathXmlApplicationContext("/spring.xml");
		Discount discount = appContext.getBean(Discount.class);
		
		double price = 10.9d;
		double dis = discount.getDiscountPrice(price);
		System.out.println("discount price is " + dis);
	}
}

在main方法中我们首先初始化了ApplicationContext的实例,然后获得了配置文件中定义的discount实例,然后就可以使用discount实例计算折扣了。

写到这里似乎没有显示出spring ioc的意义,别急,我们继续,加入我们需要另一个折扣算法,商品在每天的早上9点10分到9点半之间打五折,其他时间打7折,这就需要一个新的打折逻辑类,我们实现如下:

package cn.outofmemory.spring;

import java.util.Calendar;

public class TimedDiscount implements DiscountLogic {

	@Override
	public double calcDiscount(double price) {
		Calendar cal = Calendar.getInstance();
		int hour = cal.get(Calendar.HOUR_OF_DAY);
		int minute = cal.get(Calendar.MINUTE);
		if (hour == 9 && minute <= 20) {
			return price * .5;
		}
		return price * .7;
	}

}

 我们添加了一种新的打折算法,这是对扩展开放了,也没修改原有的代码,利用spring的ioc就可以将这个类应用到Discount实例上。

我们只需要修改spring的配置文件:

<?xml version="1.0" encoding="UTF-8"?> 
<beans xmlns="http://www.springframework.org/schema/beans" 
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
 xsi:schemaLocation="http://www.springframework.org/schema/beans 
 http://www.springframework.org/schema/beans/spring-beans.xsd"> 
 <bean class="cn.outofmemory.spring.SimpleDiscountLogic" id="simple"> 
 <property name="discountRate" value="80" /> 
 </bean> 
 <bean class="cn.outofmemory.spring.TimedDiscountLogic" id="timed"/> 
 <bean class="cn.outofmemory.spring.Discount"> 
 <property name="discountLogic" ref="timed" /> 
 </bean> 
 
</beans>

 我们在spring配置文件中添加了TimedDiscountLogic的实例timed,并且将Discount实例的discountLogic属性的实例设置为timed,再次运行程序可以看到已经使用上新的打折算法了。

使用spring的IOC可以很容易的实现开闭原则,这样设计的软件更容易维护。

抱歉!评论已关闭.