在阎宏博士的《JAVA与模式》一书中开头是这样描述简单工厂模式的:简单工厂模式是类的创建模式,又叫做静态工厂方法(Static Factory Method)模式。简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例。
举例说明适用场景:
假设应用系统需要多种登录方式:口令认证(通过数据库验证用户)、域认证(通过微软域验证用户)。建立一个支持多种登录方式的接口,见下图:
1 public interface Login {
2 //登录验证
3 public boolean verify(String name , String password);
4 }
1 public class DomainLogin implements Login {
2
3 @Override
4 public boolean verify(String name, String password) {
5 // TODO Auto-generated method stub
6 /**
7 * 业务逻辑
8 */
9 return true;
10 }
11
12 }
1 public class PasswordLogin implements Login {
2
3 @Override
4 public boolean verify(String name, String password) {
5 // TODO Auto-generated method stub
6 /**
7 * 业务逻辑
8 */
9 return true;
10 }
11
12 }
工厂类LoginManager根据不同要求创建出不同的登录对象并返回。而如果遇到非法要求,会返回一个Runtime异常。
1 public class LoginManager {
2 public static Login factory(String type){
3 if(type.equals("password")){
4
5 return new PasswordLogin();
6
7 }else if(type.equals("passcode")){
8
9 return new DomainLogin();
10
11 }else{
12 /**
13 * 这里抛出一个自定义异常会更恰当
14 */
15 throw new RuntimeException("没有找到登录类型");
16 }
17 }
18 }
测试类:
1 public class Test {
2 public static void main(String[] args) {
3 // TODO Auto-generated method stub
4 String loginType = "password";
5 String name = "name";
6 String password = "password";
7 Login login = LoginManager.factory(loginType);
8 boolean bool = login.verify(name, password);
9 if (bool) {
10 /**
11 * 业务逻辑
12 */
13 } else {
14 /**
15 * 业务逻辑
16 */
17 }
18 }
19 }
简单工厂模式的结构见下图:
把上面的Test当做一个Servlet时,客户端发起登录请求—>请求交给服务端Servlet—>Servlet根据客户端传递的loginType调用工厂类LoginManager的factory方法—>factory方法根据参数loginType创建相应的登录验证类(DomainLogin或PasswordLogin)的对象并返回—>登录验证对象调用verify方法验证用户名和密码是否正确。
如果不使用简单工厂模式则验证登录Servlet代码如下(假设Test为一个Servlet,变量loginType、name、password表示从客户端传递过来的参数):
1 public class Test {
2 public static void main(String[] args) {
3 // TODO Auto-generated method stub
4
5 String loginType = "password";
6 String name = "name";
7 String password = "password";
8 //处理口令认证
9 if(loginType.equals("password")){
10 PasswordLogin passwordLogin = new PasswordLogin();
11 boolean bool = passwordLogin.verify(name, password);
12 if (bool) {
13 /**
14 * 业务逻辑
15 */
16 } else {
17 /**
18 * 业务逻辑
19 */
20 }
21 }
22 //处理域认证
23 else if(loginType.equals("passcode")){
24 DomainLogin domainLogin = new DomainLogin();
25 boolean bool = domainLogin.verify(name, password);
26 if (bool) {
27 /**
28 * 业务逻辑
29 */
30 } else {
31 /**
32 * 业务逻辑
33 */
34 }
35 }else{
36 /**
37 * 业务逻辑
38 */
39 }
40 }
41 }
与使用简单工厂模式的代码相比,上面的代码质量很差。
简单工厂模式的优点
工厂类有创建逻辑,免除调用者直接创建对象的责任。
简单工厂模式的缺点
工厂类集中了大量的创建逻辑,逻辑判断严重影响整个系统。