原創文章,同步發自做者我的博客,轉載請註明出處 http://www.jasongj.com/design_pattern/abstract_factory/java
上文《工廠方法模式》中提到,在工廠方法模式中一種工廠只能建立一種具體產品。而在抽象工廠模式中一種具體工廠能夠建立多個種類的具體產品。git
抽象工廠模式(Factory Method Pattern)中,抽象工廠提供一系列建立多個抽象產品的接口,而具體的工廠負責實現具體的產品實例。抽象工廠模式與工廠方法模式最大的區別在於抽象工廠中每一個工廠能夠建立多個種類的產品。github
抽象工廠模式類圖以下 (點擊可查看大圖)
數據庫
與工廠方法模式相似,在建立具體產品時,客戶端經過實例化具體的工廠類,並調用其建立目標產品的方法建立具體產品類的實例。根據依賴倒置原則,具體工廠類的實例由工廠接口引用,具體產品的實例由產品接口引用。具體調用代碼以下設計模式
package com.jasongj.client; import com.jasongj.bean.Product; import com.jasongj.bean.User; import com.jasongj.dao.role.IRoleDao; import com.jasongj.dao.user.IUserDao; import com.jasongj.dao.user.product.IProductDao; import com.jasongj.factory.IDaoFactory; import com.jasongj.factory.MySQLDaoFactory; public class Client { public static void main(String[] args) { IDaoFactory factory = new MySQLDaoFactory(); IUserDao userDao = factory.createUserDao(); User user = new User(); user.setUsername("demo"); user.setPassword("demo".toCharArray()); userDao.addUser(user); IRoleDao roleDao = factory.createRoleDao(); roleDao.getRole("admin"); IProductDao productDao = factory.createProductDao(); Product product = new Product(); productDao.removeProduct(product); } }
本文所述抽象工廠模式示例代碼可從做者Github下載oop
上例是J2EE開發中經常使用的DAO(Data Access Object),操做對象(如User和Role,對應於數據庫中表的記錄)須要對應的DAO類。設計
在實際項目開發中,常常會碰到要求使用其它類型的數據庫,而不但願過多修改已有代碼。所以,須要爲每種DAO建立一個DAO接口(如IUserDao,IRoleDao和IProductDao),同時爲不一樣數據庫實現相應的具體類。代理
調用方依賴於DAO接口而非具體實現(依賴倒置原則),所以切換數據庫時,調用方代碼無需修改。code
這些具體的DAO實現類每每不禁調用方實例化,從而實現具體DAO的使用方與DAO的構建解耦。實際上,這些DAO類通常由對應的具體工廠類構建。調用方不依賴於具體工廠而是依賴於抽象工廠(依賴倒置原則,又是依賴倒置原則)。server
每種具體工廠都能建立多種產品,由同一種工廠建立的產品屬於同一產品族。例如PostgreSQLUserDao,PostgreSQLRoleDao和PostgreSQLProductDao都屬於PostgreSQL這一產品族。
切換數據庫便是切換產品族,只須要切換具體的工廠類。如上文示例代碼中,客戶端使用的MySQL,若是要換用Oracle,只需將MySQLDaoFactory換成OracleDaoFactory便可。