那麼簡單工廠模式是在什麼場景下使用呢,下面就以本人的理解舉例說明:
就拿登錄功能來說,假如應用系統需要支持多種登錄方式如:口令認證、域認證(口令認證通常是去數據庫中驗證用戶,而域認證則是需要到微軟的域中驗證用戶)。那麼自然的做法就是建立一個各種登錄方式都適用的接口,如下圖所示:
上代碼:
- package com.bankht.factory;
- /**
- * @author: 特種兵—AK47
- * @創建時間:2012-6-18 下午02:20:00
- *
- * @類說明 :建立一個各種登錄方式都適用的接口
- */
- public interface Login {
- public boolean verify(String name, String password);
- }
- package com.bankht.factory;
- /**
- * @author: 特種兵—AK47
- * @創建時間:2012-6-18 下午02:25:06
- *
- * @類說明 :域認證
- */
- public class DomainLogin implements Login {
- @Override
- public boolean verify(String name, String password) {
- // TODO Auto-generated method stub
- /**
- * 業務邏輯
- */
- return true;
- }
- }
- package com.bankht.factory;
- /**
- * @author: 特種兵—AK47
- * @創建時間:2012-6-18 下午02:27:40
- *
- * @類說明 :口令認證
- */
- public class PasswordLogin implements Login {
- @Override
- public boolean verify(String name, String password) {
- // TODO Auto-generated method stub
- /**
- * 業務邏輯
- */
- return true;
- }
- }
我們還需要一個工廠類LoginManager,根據調用者不同的要求,創建出不同的登錄對象並返回。而如果碰到不合法的要求,會返回一個Runtime異常。
- package com.bankht.factory;
- /**
- * @author: 特種兵—AK47
- * @創建時間:2012-6-18 下午02:28:02
- *
- * @類說明 :工廠類
- */
- public class LoginManager {
- public Login factory(String type) {
- if (type.equals("password")) {
- System.out.println("您從工廠裏拿的是:口令認證");
- return new PasswordLogin();
- } else if (type.equals("passcode")) {
- System.out.println("您從工廠裏拿的是:域認證");
- return new DomainLogin();
- } else {
- /**
- * 這裏拋出一個自定義異常會更恰當
- */
- throw new RuntimeException("沒有找到登錄類型");
- }
- }
- }
做一下測試:
- package com.bankht.factory;
- import org.junit.Test;
- /**
- * @author: 特種兵—AK47
- * @創建時間:2012-6-18 下午02:31:41
- *
- * @類說明 :測試工廠類
- */
- public class TestFactory {
- @Test
- public void testFactory() {
- // TODO Auto-generated method stub
- String loginType = "password";
- String name = "name";
- String password = "password";
- Login login = new LoginManager().factory(loginType);
- boolean bool = login.verify(name, password);
- if (bool) {
- /**
- * 業務邏輯
- */
- } else {
- /**
- * 業務邏輯
- */
- }
- }
- }
測試結果:
- 您從工廠裏拿的是:口令認證
簡單工廠模式的結構如下圖:
我們可以設想一下真實的場景,如果把上面的Test當做一個servlet的話,當客戶端發起登錄請求——>請求交給服務端的Servlet——>Servlet根據客戶端傳遞的loginType調用工廠類LoginManager的factory()方法——>factory()方法根據參數loginType創建相應的登錄驗證類(DomainLogin或PasswordLogin)並返回——>登錄驗證類調用方法verify()驗證用戶名密碼是否正確
假如不使用簡單工廠模式則驗證登錄Servlet代碼如下(假設Test爲一個Servlet,變量loginType、name、password表示從客戶端傳遞過來的參數):
- package com.bankht.factory;
- /**
- * @author: 特種兵—AK47
- * @創建時間:2012-6-19 下午02:26:45
- *
- * @類說明 :
- */
- public class Test {
- public static void main(String[] args) {
- // TODO Auto-generated method stub
- String loginType = "password";
- String name = "name";
- String password = "password";
- // 處理口令認證
- if (loginType.equals("password")) {
- PasswordLogin passwordLogin = new PasswordLogin();
- boolean bool = passwordLogin.verify(name, password);
- if (bool) {
- /**
- * 業務邏輯
- */
- } else {
- /**
- * 業務邏輯
- */
- }
- }
- // 處理域認證
- else if (loginType.equals("passcode")) {
- DomainLogin domainLogin = new DomainLogin();
- boolean bool = domainLogin.verify(name, password);
- if (bool) {
- /**
- * 業務邏輯
- */
- } else {
- /**
- * 業務邏輯
- */
- }
- } else {
- /**
- * 業務邏輯
- */
- }
- }
- }
上面的代碼會不會很蛋疼啊。。。呵呵
《JAVA與模式》一書中使用java.text.DataFormat類作爲簡單工廠模式的典型例子敘述。
簡單工廠模式的優點
模式的核心是工廠類。這個類含有必要的邏輯判斷,可以決定在什麼時候創建哪一個登錄驗證類的實例,而調用者則可以免除直接創建對象的責任。簡單工廠模式通過這種做法實現了對責任的分割,當系統引入新的登錄方式的時候無需修改調用者。
簡單工廠模式的缺點
這個工廠類集中了所有的創建邏輯,當有複雜的多層次等級結構時,所有的業務邏輯都在這個工廠類中實現。什麼時候它不能工作了,整個系統都會受到影響。