上一章我们着重讨论了代理模式,以及其实现原理,相信如果你看完了整篇博文,应该就对代理模式很熟悉了。
本章我们讨论简单工厂模式,LZ当初不小心夸下海口说不和网络上传播的教学式模式讲解雷同,所以现在感觉写一篇博文压力颇大。
如何来介绍简单工厂呢,LZ着实费了不少心思,这个模式本身不复杂,但其实越是不复杂的模式越难诠释,所以要诠释这个模式,LZ还是觉得一定要使用各位用过的场景,本人不太喜欢自己捏造场景,所以就只好拿我们经常使用的struts2来开刀,但是我们无法使用struts2的源码来诠释,不是因为不行,而是简单工厂相对来说是一个比较低级点的工厂模式,所以struts2这种框架里,很难找到典型的纯粹的使用这个模式的地方,至少LZ目前没找到。
所以LZ会拿我们自己的创造的项目来做例子,但会尽量贴近实际应用。
众所周知,我们平时开发web项目是以spring作为平台,来集成各个组件,比如集成struts2来完成业务层与表现层的逻辑,集成hibernate或者ibatis来完成持久层的逻辑。
struts2在这个过程当中提供了分离数据持久层,业务逻辑层以及表现层的责任,有了Struts2,我们不再需要servlet,而是可以将一个普通的Action类作为处理业务逻辑的单元,然后将表现层交给特定的视图去处理,比如JSP,template等等。
我们来尝试着写一个非常非常简单的web项目,来看看在没有struts2的时候,我们都是怎么过的。
我会省略WEB架构过程当中的很多细节,所以最好是各位亲手做过一些项目,最起码也自己搭建过WEB项目,我相信既然有兴趣来看设计模式,应该都至少有过这种锻炼。
下面我把我们需要的类都列出来,并加上简单的注释。
[html]
import javax.servlet.http.HttpServlet;
//假设这是一个小型的WEB项目,我们通常里面会有这些类
//这个类在代理模式出现过,是我们的数据源连接池,用来生产数据库连接。
class DataSource{}
//我们一般会有这样一个数据访问的基类,这个类要依赖于数据源
class BaseDao{}
//一般会有一系列这样的DAO去继承BaseDao,这一系列的DAO类便是数据持久层
class UserDao extends BaseDao{}
class PersonDao extends BaseDao{}
class EmployeeDao extends BaseDao{}
//我们还会有一系列这样的servlet,他们通常依赖于各个Dao类,这一系列servlet便是我们的业务层
class LoginServlet extends HttpServlet{}
class LoginOutServlet extends HttpServlet{}
class RegisterServlet extends HttpServlet{}
//我们通常还会有HTML页面或者JSP页面,但是这个本次不在考虑范围内,这便是表示层。
import javax.servlet.http.HttpServlet;
//假设这是一个小型的WEB项目,我们通常里面会有这些类
//这个类在代理模式出现过,是我们的数据源连接池,用来生产数据库连接。
class DataSource{}
//我们一般会有这样一个数据访问的基类,这个类要依赖于数据源
class BaseDao{}
//一般会有一系列这样的DAO去继承BaseDao,这一系列的DAO类便是数据持久层
class UserDao extends BaseDao{}
class PersonDao extends BaseDao{}
class EmployeeDao extends BaseDao{}
//我们还会有一系列这样的servlet,他们通常依赖于各个Dao类,这一系列servlet便是我们的业务层
class LoginServlet extends HttpServlet{}
class LoginOutServlet extends HttpServlet{}
class RegisterServlet extends HttpServlet{}
//我们通常还会有HTML页面或者JSP页面,但是这个本次不在考虑范围内,这便是表示层。
以上是我们小型WEB项目大体的结构,可以看到LZ写了三个Servlet,没有写具体的实现到底如何,但是不难猜测,三个servlet的功能分别是进行登录,注销,以及注册新用户的功能。我们的servlet一般都是继承自HttpServlet,因为我们在web.xml配置servlet时,所写入的Class需要实现servlet接口,而我们通常采用的传输协议都是HTTP,所以HttpServlet就是我们最好的选择了,它帮我们完成了基本的实现。
但是这样我们有很多限制,比如我们一个servlet一般只能负责一个单一的业务逻辑,因为我们所有的业务逻辑通常情况下都集中在doPost这样一个方法当中,可以想象下随着业务的增加,我们的servlet数量会高速增加,这样不仅项目的类会继续增加,最最恶心的是,我们每添加一个servlet就要在web.xml里面写一个servlet配置。
但是如果我们让一个Servlet负责多种业务逻辑的话,那我们需要在doPost方法中加入很多if判断,去判断当前的操作。
比如我们将上述三个servlet合一的话,你会在doPost出现以下代码。
[java]
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//我们加入一个操作的参数,来让servlet做出不同的业务处理
String operation = req.getParameter("operation");
if (operation.equals("login")) {
System.out.println("login");
}else if (operation.equals("register")) {
System.out.println("register");
}else if (operation.equals("loginout")) {
System.out.println("loginout");
}else {
throw new RuntimeException("invalid operation");
}
}
protected void doPost(HttpServletRequest