設計模式做爲一套被反覆使用、多數人知曉的、通過分類編目的、代碼設計經驗的總結,在現代軟件開發過程當中獲得了充分的利用。使代碼更容易被他人理解,保證代碼的可靠性。對於一個還沒有接觸過大型軟件開發的學生,在軟件開發過程當中我使用的設計模式也比較少,而且一般是利用現有框架進行軟件的開發,所以,我學習了一下在spring框架中所使用到的設計模式,並就此作一些總結和嘗試。在java衆多開源框架中,做爲一個輕量級java開發框架,spring通過十幾年的發展,已經成爲了java SE/EE最流行的開發框架,不管在架構設計方面仍是代碼編寫方面,都當作行內典範。java
Spring中經常使用的設計模式有九種,下面將選擇其中的兩種作詳細的介紹。spring
第一種,簡單工廠模式。簡單工廠模式又叫靜態工廠方法模式,可是不屬於23種經典模式之一。簡單來講,簡單工廠模式就是定義一個類來專門建立其餘類的實例,被建立的實例一般具備相同的父類。數據庫
舉一個簡單的例子就是小明想請一些同窗吃飯,可是他本身又不會作飯,因此小明將同窗帶到了肯德基,同窗們本身點餐,而他只負責付錢。那麼在這裏,肯德基就是一個食物工廠,同窗小紅點了一份炸雞,工廠就實例化一份炸雞;小華點了一份漢堡,工廠就實例化一份漢堡。全部食物都繼承自「食物」接口。apache
如圖建立5個類:設計模式
Food接口:session
public interface Food {架構
public void get();app
}框架
Chicken類:ide
public class Chicken implements Food {
public void get() {
System.out.println("chicken");
}
}
Hamburg類:
public class Hamburg implements Food {
public void get() {
System.out.print("hamburg");
}
}
工廠類:
public class FoodFactory {
public static Food getFood(String food) throws Exception{
if(food.equalsIgnoreCase("chicken")){
return Chicken.class.newInstance();
}else if(food.equalsIgnoreCase("hamburg")){
return Hamburg.class.newInstance();
}else{
System.out.print("There is no such food!");
return null;
}
}
}
最後是測試:
public class Test {
public static void main(String []args) throws Exception {
String xiaohong = "chicken";
String xiaohua = "hamburg";
Food a = FoodFactory.getFood(xiaohong);
Food b = FoodFactory.getFood(xiaohua);
a.get();
b.get();
}
}
輸出結果如圖所示:
返回了小紅和小華點的對應食物。
在spring中,BeanFactory擁有相似的功能,它負責實例化、配置和管理對象。咱們通常用的BeanFactory的實現類ApplicationContext,這個類會自動解析咱們配置的applicationContext.xml,而後根據咱們配置的bean來new對象,將new好的對象放進一個Map中,鍵就是咱們bean的id,值就是new的對象。下面是一個簡化版的BeanFactory的應用:
BeanFactory接口:
public interface BeanFactory {
Object getBean(String id);
}
一個BeanFactory的實現類ClassPathXmlApplicationContext,用以讀取配置信息:
public class ClassPathXmlApplicationContext implements BeanFactory {
private Map<String, Object> beans = new HashMap<String, Object>();
public ClassPathXmlApplicationContext(String fileName) throws Exception{
SAXReader reader = new SAXReader();
Document document = reader.read(this.getClass().getClassLoader().getResourceAsStream(fileName));
List<Element> elements = document.selectNodes("/beans/bean");
for (Element e : elements) {
String id = e.attributeValue("id");
String value = e.attributeValue("class");
Object o = Class.forName(value).newInstance();
beans.put(id, o);
}
}
public Object getBean(String id) {
return beans.get(id);
}
}
配置信息applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans>
<bean id="c" class="com.spring.Car"></bean>
<bean id="p" class="com.spring.Plane"></bean>
</beans>
測試類:
public class Test {
public static void main(String[] args) throws Exception {
BeanFactory factory = new ClassPathXmlApplicationContext("applicationContext.xml");
Object o = factory.getBean("c");
System.out.println(o.getClass().toString());
}
}
輸出結果:
以上就是spring中工廠模式的應用的一個例子。BeanFactory只是其中的一種應用,spring中還有不少工廠模式的應用,留待之後認真學習。
第二種,裝飾模式。裝飾模式也叫包裝器模式,指動態地給一個對象添加一些額外的職責。就增長功能來講,Decorator模式相比生成子類更爲靈活。
一個簡單的例子就是用戶需求打印一句話,那麼就能夠這樣實現:
接口PrintHandler:
public interface PrintHandler {
public String filter(String msg);
}
接口實現類PrintMessage:
public class PrintMessage implements PrintHandler {
public String filter(String msg) {
return msg;
}
}
測試類Test:
public class Test {
public static void main(String[] args) {
PrintHandler ph = new PrintMessage ();
String s = ph.filter("今每天氣真好!");
System.out.println(s);
}
}
輸出結果爲:
如今客戶提出了新的需求,須要在輸出信息前面加上「提示信息」幾個字。直接更改PrintMessage實現類不太好,由於可能在軟件其餘地方使用到了該方法。那麼就能夠用到裝飾器模式,代碼以下:
裝飾器類PrintHandlerDecorator
public class PrintHandlerDecorator implements PrintHandler {
private PrintHandler handler;
public PrintHandlerDecorator(PrintHandler handler) {
super();
this.handler = handler;
}
public String filter(String msg) {
return handler.filter(msg);
}
}
具體實現類DetailDecorator:
public class DetailDecorator extends PrintHandlerDecorator {
public DetailDecorator (PrintHandler handler) {
super(handler);
}
public String filter(String content) {
String temp = "提示信息";
temp += super.filter(content);
return temp;
}
}
測試類Test:
public class Test {
public static void main(String[] args) {
PrintHandler mb = new PrintMessage ();
mb = new PrintHandlerDecorator (new DetailDecorator (new PrintMessage ()));
content = mb.filter("今每天氣真好");
System.out.println(content);
}
}
以上就是裝飾模式的一個簡單的例子,在spring中,開發人員最熟悉的裝飾模式的應用應該就是dataSource了。有時在項目中須要鏈接多個數據庫,並且不一樣的客戶在每次訪問中根據須要會去訪問不一樣的數據庫。咱們以往在spring和hibernate框架中老是配置一個數據源,於是sessionFactory的dataSource屬性老是指向這個數據源而且恆定不變,全部DAO在使用sessionFactory的時候都是經過這個數據源訪問數據庫。可是如今,因爲項目的須要,咱們的DAO在訪問sessionFactory的時候都不得不在多個數據源中不斷切換,這就給開發帶來了至關大的難度和性能影響。
在spring的applicationContext中能夠配置全部的dataSource。這些dataSource多是各類不一樣類型的,好比不一樣的數據庫:Oracle、SQL Server、MySQL等,也多是不一樣的數據源:好比apache 提供的org.apache.commons.dbcp.BasicDataSource、spring提供的org.springframework.jndi.JndiObjectFactoryBean等。而後sessionFactory根據客戶的每次請求,將dataSource屬性設置成不一樣的數據源,以到達切換數據源的目的。
spring中用到的包裝器模式在類名上有兩種表現:一種是類名中含有Wrapper,另外一種是類名中含有Decorator。基本上都是動態地給一個對象添加一些額外的職責。
總之,做爲一款優秀的框架,spring在設計模式上的應用顯得很是巧妙,還須要我更深刻的理解學習。