1. 程式人生 > >Java結合反射和單例的工廠模式

Java結合反射和單例的工廠模式

轉自:http://seekereye.iteye.com/blog/446688

所謂的工廠模式是通過向這個工廠提供一些“原材料”,然後工廠就可以生產出相應的“產品”的一種模式。在Java中所具體對應的是:通過提供一個類,然後生產出物件的模式;當然也可以提供其他的東西而生產出另外一種東西。不管提供什麼、生產什麼,主要的是工廠本身,工廠的作用。在Java程式設計中工廠模式很有用,也很常用,實現起來也不難;在實現時需要結合一些東西,如反射、單例等,下面是一個簡單的例子: 
1、定義一個介面。介面可以多實現,很容易實現多型,很有好處; 

Java程式碼  收藏程式碼
  1. public interface DAOIf{  
  2.        void test();   
  3. }  

介面中隨意定義了一個方法,一般人都知道實現這個介面的具體類要實現介面中方法。 

2、這裡再定義兩個實現上述介面的具體類,也就是具有相同業務邏輯的類,使用時可以隨意切換; 
Java程式碼  收藏程式碼
  1. public class DAOimpl1 implements DAOIf{  
  2.        public void test(){  
  3.               System.out.println("this is implement1");  
  4.        }  
  5. }  
  6. public class DAOimpl2 implements
     DAOIf{  
  7.        public void test(){  
  8.               System.out.println("this is implement2");  
  9.        }  
  10. }  

3、寫一個用於反射具體類的工廠,而反射時只需反射出具體類的一個例項,所以要用到單例模式。如 果在切換實現類時不想修改原始碼,可以把類名寫在配置檔案中,然後讀出來即可; 
工廠的寫法有兩種:一種是餓漢式,一種是懶漢式。 
      餓漢式: 
Java程式碼  收藏程式碼
  1. public class DAOFactory {  
  2.     private static Properties pro;  
  3.     private static DAOIf dao;  
  4.     static {  
  5.         pro = new Properties();  
  6.         try {  
  7.             FileInputStream fis = new FileInputStream("DAO.config");  
  8.             pro.load(fis);  
  9.             String clsName = pro.getProperty("implClasse");  
  10.             Class cls = Class.forName(clsName);  
  11.             dao = (DAOIf) cls.newInstance();  
  12.         } catch (Exception e) {  
  13.             e.printStackTrace();  
  14.         }  
  15.     }  
  16.     // 負責向外界返回dao的例項  
  17.     public static DAOIf getDao() throws Exception {  
  18.         return dao;  
  19.     }  
  20. }  

可以看到,之所以稱為餓漢式是因為物件在程式初始化時就在靜態程式碼中被建立,而不管使用者是否使用它。程式中的"DAO.config"是一個儲存有類名資訊的配置檔案。 
       懶漢式: 
Java程式碼  收藏程式碼
  1. public class DAOFactory {  
  2.     private static Properties pro;  
  3.     private static DAOIf dao;  
  4.     static {  
  5.         pro = new Properties();  
  6.         try {  
  7.             FileInputStream fis = new FileInputStream("DAO.config");  
  8.             pro.load(fis);  
  9.         } catch (Exception e) {  
  10.             e.printStackTrace();  
  11.         }  
  12.     }  
  13.     // 負責向外界返回dao的例項  
  14.     public static DAOIf getDao() throws Exception {  
  15.         if (dao == null) {  
  16.             String clsName = pro.getProperty("implClasse");  
  17.             Class cls = Class.forName(clsName);  
  18.             dao = (DAOIf) cls.newInstance();  
  19.         }  
  20.         return dao;  
  21.     }  
  22. }  

懶漢式中只有當呼叫了返回例項的方法時物件才會被建立; 
兩種寫法都只建立一個例項,所以都是單例的;單例可以節約資源。 
DAO.config配置檔案的具體內容為:implClasse=DAOimpl1;這裡的實現類可任意切換。這樣工廠就基本完成。在使用時工廠就會根據配置檔案所提供的實現類反射出物件,而我們如果要切換實現類,只需要修改一下配置檔案即可,但不需要修改原始碼。這樣做的好處是,哪個實現類好我們就用哪個,方便移植。 
由此看到工廠模式很靈活,也很好用,在程式設計時如果用得上工廠模式都應該使用。