Spring中的設計模式

 

         設計模式做爲一套被反覆使用、多數人知曉的、通過分類編目的、代碼設計經驗的總結,在現代軟件開發過程當中獲得了充分的利用。使代碼更容易被他人理解,保證代碼的可靠性。對於一個還沒有接觸過大型軟件開發的學生,在軟件開發過程當中我使用的設計模式也比較少,而且一般是利用現有框架進行軟件的開發,所以,我學習了一下在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 {

    @Override

    public void get() {

        System.out.println("chicken");

    }

}

Hamburg類:

    public class Hamburg implements Food {

    @Override

    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在設計模式上的應用顯得很是巧妙,還須要我更深刻的理解學習。

相關文章
相關標籤/搜索