在java的設計模式中,工廠模式被廣泛使用,因此有必要了解一下什么是工廠模式,以及它所具有的的優點,應用場景等等......
一、定義:實例化對象,用工廠方法代替new操作。
二、如何實現
工廠模式主要是定義一個接口來創建對象,但是讓子類來決定哪些類需要被實例化,工廠方法把實例化的工作推遲到子類中去實現。
三、分類
- 工廠方法模式
- 抽象工廠模式
二者之間的對比:
- 工廠模式是一種極端情況下的抽象工廠模式,而抽象工廠模式可以看成是工廠模式的推廣。
- 工廠模式用來創建一個產品的等級結構,而抽象工廠模式是用來創建多個產品的等級結構。
- 工廠模式只有一個抽象產品類,而抽象工廠模式有多個抽象產品類。
四、例子(工廠方法模式)
首先,創建對應的接口
/** * 幾何圖形接口 * */ public interface Geometry { //創建幾何圖形 public void creat(); }
然后創建一系列接口的實現類
//實現類1:正方形 public class Square implements Geometry { @Override public void creat() { System.out.println("-------------正方形--------------"); } } //實現類2:長方形 public class Oblong implements Geometry { @Override public void creat() { System.out.println("-------------長方形--------------"); } } //實現類3:圓形 public class Rotundity implements Geometry { @Override public void creat() { System.out.println("-------------圓形--------------"); } }
接着需要編寫工廠,不過我們先寫測試方法
public class Test { public static void main(String[] args) { GeometryFactory factory = new GeometryFactory(); Geometry geometry = factory.getByClassKey("Rotundity"); geometry.creat(); } }
在測試方法中,我們調用工廠中的getByClassKey方法,我們希望傳過去一個值,工廠中的方法能夠根據傳的值直接定義到我們需要實例的對象,因此我們需要進行一個封裝,將傳的值和對應的類名一一對應封裝,類似於map中的鍵值對形式,在java中封裝值可以寫在properties文件中,二者之間用等號連接。
Square=com.xm.entity.Square Oblong=com.xm.entity.Oblong Rotundity=com.xm.entity.Rotundity
封裝完對應關系后,我們需要寫一個創建一個類來專門解讀properties文件中的對應關系,其原理是將其對應的關系存放進一個map中,等號左邊作為map的key值,右邊作為map的value值。
/** * properties文件讀取工具 * */ public class ReaderProperties { public Map<String,String> getProperties(){ Properties props = new Properties(); Map<String,String> map = new HashMap<String,String>(); try { InputStream in = getClass().getResourceAsStream("app.properties"); props.load(in); Enumeration en = props.propertyNames(); while(en.hasMoreElements()){ String key = (String) en.nextElement(); String property = props.getProperty(key); map.put(key, property); } } catch (IOException e) { e.printStackTrace(); } return map; } }
接下來就要編寫工廠方法了,在工廠類中,我們使用反射來通過類名直接找到我們需要的類,這樣代碼更具有通用性和擴展性。
public class GeometryFactory { //根據類名來生產對象 public Geometry getByClassKey(String key){ Map<String,String> map = new ReaderProperties().getProperties(); try { Geometry geometry = (Geometry)Class.forName(map.get(key)).newInstance(); return geometry; } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (ClassNotFoundException e) { e.printStackTrace(); } return null; } }
五、工廠模式的常見應用
1、JDBC
JDBC是一種用於執行SQL語句的java API,可以為多種關系數據庫提供統一訪問,它由一組用java語言編寫的類和接口組成。
2、spring beanfactory
BeanFactory,作為Spring基礎的IOC容器,是Spring的一個Bean工廠,如果單從工廠模式的角度思考,它就是用來“生產Bean”,然后提供給客戶端。
六、工廠模式的作用
- 系統可以在不修改具體工廠角色的情況下引入新的產品。
- 客戶端不必關心對象如果創建,明確了職責。
- 更好的理解面向對象的原則,面向接口編程,而不是面向實現編程。
七、工廠模式的適用場景
- 一個系統應當不依賴於產品類實例被創立,組成,和表示的細節。這對於所有形態的工廠模式都是重要的。
- 這個系統的產品有至少一個的產品族。
- 同屬於同一產品族的產品是設計成在一起使用的,這一約束必須得在系統的設計中體現出來。
- 不同的產品以一系列的接口的面貌出現,從而使系統不依賴與接口實現的細節。