在閻宏博士的《JAVA與模式》一書中開頭是這樣描述簡單原廠模式的:簡單原廠模式是類的建立模式,又叫做靜態Factory 方法(Static Factory Method)模式。簡單原廠模式是由一個工廠對象決定建立出哪一種產品類的執行個體。
那麼簡單原廠模式是在什麼情境下使用呢,下面就以本人的理解舉例說明:
就拿登入功能來說,假如應用系統需要支援多種登入方式如:口令認證、域認證(口令認證通常是去資料庫中驗證使用者,而域認證則是需要到微軟的域中驗證使用者)。那麼自然的做法就是建立一個各種登入方式都適用的介面,如所示:
public interface Login {
//登入驗證
public boolean verify(String name , String password);
}
public class DomainLogin implements Login {
@Override
public boolean verify(String name, String password) {
// TODO Auto-generated method stub
/**
* 商務邏輯
*/
return true;
}
}
public class PasswordLogin implements Login {
@Override
public boolean verify(String name, String password) {
// TODO Auto-generated method stub
/**
* 商務邏輯
*/
return true;
}
}
我們還需要一個工廠類LoginManager,根據調用者不同的要求,建立出不同的登入對象並返回。而如果碰到不合法的要求,會返回一個Runtime異常。
public class LoginManager {
public static Login factory(String type){
if(type.equals("password")){
return new PasswordLogin();
}else if(type.equals("passcode")){
return new DomainLogin();
}else{
/**
* 這裡拋出一個自訂異常會更恰當
*/
throw new RuntimeException("沒有找到登入類型");
}
}
}
測試類別:
public class Test {
public static void main(String[] args) {
// TODO Auto-generated method stub
String loginType = "password";
String name = "name";
String password = "password";
Login login = 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表示從用戶端傳遞過來的參數):
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類作為簡單原廠模式的典型例子敘述。
簡單原廠模式的優點
模式的核心是工廠類。這個類含有必要的邏輯判斷,可以決定在什麼時候建立哪一個登入驗證類的執行個體,而調用者則可以免除直接建立對象的責任。簡單原廠模式通過這種做法實現了對責任的分割,當系統引入新的登入方式的時候無需修改調用者。
簡單原廠模式的缺點
這個工廠類集中了所以的建立邏輯,當有複雜的多層次等級結構時,所有的商務邏輯都在這個工廠類中實現。什麼時候它不能工作了,整個系統都會受到影響。