1. 程式人生 > >設計模式筆記之工廠模式--簡單工廠模式(Simple Factory Pattern)

設計模式筆記之工廠模式--簡單工廠模式(Simple Factory Pattern)

一、概述:

工廠模式就是專門負責將大量有共同介面的類例項化,而且不必事先知道每次是要例項化哪一個類的模式。它定義一個用於建立物件的介面,由子類決定例項化哪一個類。

二、簡單工廠模式的結構:

三、簡單的例項:

1.定義一個介面,代表一類Javabean

public interface UserDao {
 public void save();
}

2.定義UserDao的實現類:
public class UserDaoWithMySql implements UserDao{
 public void save(){
  System.out.println("mysql save");
 }
}
public class UserDaoWithOracle implements UserDao{
 public void save(){
  System.out.println("Oracle Save!");
 }
}

3.定義用來產生UserDao的工廠:
/**
 * 用來產生UserDao的工廠
 * @author yu
 *
 */
public class UserDaoFactory {
 public static UserDao create(){
//  return new UserDaoWithMySql();
  return new UserDaoWithOracle();
 }
}

4.測試:
UserDao ud = UserDaoFactory.create();
  ud.save();

使用的時候要獲取不同的實現類,只需要改變UserDaoFactory的返回值就行了,但還是顯得不夠靈活,且看下面的例子:

四、會延遲載入Bean的BeanFactory:

1.定義一個properties檔案:bean.properties:

mysql=com.cxy.factory.simple.UserDaoWithMySql
oracle=com.cxy.factory.simple.UserDaoWithOracle
2.定義BeanFactory(BeanFactory_lazy):
package com.cxy.factory.simple;

import java.io.IOException;
import java.util.Properties;

public class BeanFactory_lazy {
  private static Properties pro;
  static{
     pro = new Properties();
     try {
       //讀取properties檔案
       pro.load(BeanFactory_lazy.class.getClassLoader().getResourceAsStream("bean.properties"));
     } catch (IOException e) {
       e.printStackTrace();
     }
  }
  public static UserDao getBean(String key){
     if(pro.containsKey(key)){
       String className = pro.getProperty(key);
       try {
          return (UserDao) Class.forName(className).newInstance();
       } catch (InstantiationException e) {
          e.printStackTrace();
       } catch (IllegalAccessException e) {
          e.printStackTrace();
       } catch (ClassNotFoundException e) {
          e.printStackTrace();
       }
       return null;
     }else{
       throw new IllegalArgumentException();
     }
  }
}
 

3.測試:
UserDao ud = BeanFactory_lazy.getBean("oracle");
ud.save();
實際應用中可以根據需要給getBean()方法傳入不同的引數,即可獲取不同的Bean

上面的程式碼中,雖然實現了靈活的獲取Bean的方法,但是隻有在用到Bean的時候才會例項化對應的Bean,有時候我們想讓初始化BeanFactory的時候就將配置的Bean都建立好,且看下面的程式碼:
4.非延遲載入的BeanFactory

package com.cxy.factory.simple;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.util.Map.Entry;

public class BeanFactory {
  private static Properties pro;
  //用來存放properties檔案中的資訊
  private static Map<String,Object> map = new HashMap<String, Object>();
 static{
     pro = new Properties();
     try {
       pro.load(BeanFactory.class.getClassLoader().getResourceAsStream("bean.properties"));
     } catch (IOException e) {
       e.printStackTrace();
     }
     //迭代該properties檔案,將其內容讀入到map中
     for(Entry<Object ,Object> entry : pro.entrySet() ){
       String key = (String) entry.getKey();
       String className = (String) entry.getValue();
       try {
          Object userDao = Class.forName(className).newInstance();
          map.put(key, userDao);
       } catch (InstantiationException e) {
          e.printStackTrace();
       } catch (IllegalAccessException e) {
          e.printStackTrace();
       } catch (ClassNotFoundException e) {
          e.printStackTrace();
       }
     }
  }
  public static UserDao getBean(String key){
     if(map.containsKey(key)){
       return (UserDao) map.get(key);
     }else{
       throw new IllegalArgumentException();
     }
  }
}
 
將例項化Bean的步驟放在static靜態塊內,那麼在例項化該類之前就會建立所有的Bean物件,在用到的時候直接拿就可以了

上面的程式碼是Spring中BeanFactory的簡單實現,只不過Spring使用的是Xml配置檔案,這個到無所謂,原理最重要,實現途徑倒是其次