在閻宏博士的《JAVA與模式》一書中開頭是這樣描述簡單工廠模式的:簡單工廠模式是類的創(chuàng)建模式,又叫做靜態(tài)工廠方法(Static Factory Method)模式。簡單工廠模式是由一個工廠對象決定創(chuàng)建出哪一種產(chǎn)品類的實(shí)例。
那么簡單工廠模式是在什么場景下使用呢,下面就以本人的理解舉例說明:
就拿登錄功能來說,假如應(yīng)用系統(tǒng)需要支持多種登錄方式如:口令認(rèn)證、域認(rèn)證(口令認(rèn)證通常是去數(shù)據(jù)庫中驗(yàn)證用戶,而域認(rèn)證則是需要到微軟的域中驗(yàn)證用戶)。那么自然的做法就是建立一個各種登錄方式都適用的接口,如下圖所示:
public interface Login {
//登錄驗(yàn)證
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
/**
* 業(yè)務(wù)邏輯
*/
return true;
}
}
public class PasswordLogin implements Login {
@Override
public boolean verify(String name, String password) {
// TODO Auto-generated method stub
/**
* 業(yè)務(wù)邏輯
*/
return true;
}
}
我們還需要一個工廠類LoginManager,根據(jù)調(diào)用者不同的要求,創(chuàng)建出不同的登錄對象并返回。而如果碰到不合法的要求,會返回一個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{
/**
* 這里拋出一個自定義異常會更恰當(dāng)
*/
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) {
/**
* 業(yè)務(wù)邏輯
*/
} else {
/**
* 業(yè)務(wù)邏輯
*/
}
}
}
簡單工廠模式的結(jié)構(gòu)如下圖:
我們可以設(shè)想一下真實(shí)的場景,如果把上面的Test當(dāng)做一個servlet的話,當(dāng)客戶端發(fā)起登錄請求——>請求交給服務(wù)端的Servlet——>Servlet根據(jù)客戶端傳遞的loginType調(diào)用工廠類LoginManager的factory()方法——>factory()方法根據(jù)參數(shù)loginType創(chuàng)建相應(yīng)的登錄驗(yàn)證類(DomainLogin或PasswordLogin)并返回——>登錄驗(yàn)證類調(diào)用方法verify()驗(yàn)證用戶名密碼是否正確
假如不使用簡單工廠模式則驗(yàn)證登錄Servlet代碼如下(假設(shè)Test為一個Servlet,變量loginType、name、password表示從客戶端傳遞過來的參數(shù)):
public class Test {
public static void main(String[] args) {
// TODO Auto-generated method stub
String loginType = "password";
String name = "name";
String password = "password";
//處理口令認(rèn)證
if(loginType.equals("password")){
PasswordLogin passwordLogin = new PasswordLogin();
boolean bool = passwordLogin.verify(name, password);
if (bool) {
/**
* 業(yè)務(wù)邏輯
*/
} else {
/**
* 業(yè)務(wù)邏輯
*/
}
}
//處理域認(rèn)證
else if(loginType.equals("passcode")){
DomainLogin domainLogin = new DomainLogin();
boolean bool = domainLogin.verify(name, password);
if (bool) {
/**
* 業(yè)務(wù)邏輯
*/
} else {
/**
* 業(yè)務(wù)邏輯
*/
}
}else{
/**
* 業(yè)務(wù)邏輯
*/
}
}
}
上面的代碼會不會很蛋疼啊。。。呵呵
《JAVA與模式》一書中使用java.text.DataFormat類作為簡單工廠模式的典型例子敘述。
簡單工廠模式的優(yōu)點(diǎn)
模式的核心是工廠類。這個類含有必要的邏輯判斷,可以決定在什么時候創(chuàng)建哪一個登錄驗(yàn)證類的實(shí)例,而調(diào)用者則可以免除直接創(chuàng)建對象的責(zé)任。簡單工廠模式通過這種做法實(shí)現(xiàn)了對責(zé)任的分割,當(dāng)系統(tǒng)引入新的登錄方式的時候無需修改調(diào)用者。
簡單工廠模式的缺點(diǎn)
這個工廠類集中了所以的創(chuàng)建邏輯,當(dāng)有復(fù)雜的多層次等級結(jié)構(gòu)時,所有的業(yè)務(wù)邏輯都在這個工廠類中實(shí)現(xiàn)。什么時候它不能工作了,整個系統(tǒng)都會受到影響。