JAVA随笔

 

使用façade、template pattern搭建MVC框架

网络上有很多介绍 MVC 的理论知识(至于理论知识,我们不多做介绍),我也看到了一些其他人员开发的基于 MVC 的框架。对此我也有些自己的见解。通过使用 façade,template,factory pattern 搭建了一个简易的 MVC 框架。

 

OK ,我们先来个类图。

class digram.jpg

介绍下各自类的用途, FacadeServlet 主要应用为分发类,而 AbstractLogic 应用了 template pattern ,它是一个抽象类,包括一个抽象方法 doBusiLogic(HttpServletRequest request, HttpServletResponse response) 方法。像 struts 一样,若新增一个 controller ,需新增一个实现 Action execute() 方法的类。在 struts-config.xml 中配置,通过页面 url 确定执行哪个类的。在本实例中执行 doBusiLogic(HttpServletRequest request, HttpServletResponse response) 方法(注: struts 中根据配置执行方法不一样)。有点糊涂,别急,来个时序图,详细说明。


sequece.jpg

首先通过 URL 访问 FacadeServlet FacadeServlet 在全局应用中只存在一个。取得具体配置实现类(有点像 struts 应用。通过 java 反射机制实例化配置类。调用 execute() 方法分发。代码如下(含注释):

package  com.qujingbo;

import  javax.servlet.http.HttpServlet;
import  javax.servlet.http.HttpServletRequest;
import  javax.servlet.http.HttpServletResponse;
import  javax.servlet.ServletException;
import  java.io.IOException;
/**
 * <p/> Title:
 * </p>
 * <p/> Description:
 * </p>
 * <p/> Date:2004-9-7 14:50:25
 * </p>
 * 
 * 
@author  EOMS 曲静波
 * 
@version  1.0
 
*/

public   class  FacadeServlet  extends  HttpServlet 
{
   
public   void  doPost(HttpServletRequest request, HttpServletResponse response)  throws  ServletException, IOException 
   
{
         
// 在web.xml中配置
         
// <servlet>
       
// <servlet-name>FacadeServlet</servlet-name>
       
// <servlet-class>FacadeServlet</servlet-class> 
      
// <init-param>
        
// <param-name>100</param-name>
      
// <param-value>com.qujingbo.InsertDB</param-value>
      
// </init-param>
      
// <init-param>
        
// <param-name>101</param-name>
      
// <param-value>com.qujingbo.LoginCheckBusiLogic</param-value>
      
// </init-param>
      
// </servlet>
      
// 通过页面传过来的action,以该实例为准,若jsp传过来的action=100。这时String action="com.qujingbo.InsertDB"
      
// web.xml中配置的内容可以写入像struts那种struts-config.xml那种做为配置文件,定义规范,容器管理。
      String action  =  request.getParameter( " action " );
      
if (action  ==   null   ||   "" .equals(action)) 
      
{
         System.out.println(
" no action " );
         
return ;
      }

      
try  
      
{
           
// 通过java反射机制实例化com.qujingbo.InsertDB
         String strClassName  =   this .getInitParameter(action);
         Class cls 
=  Class.forName(strClassName);
         AbstractLogic _AbstractLogic 
=  (AbstractLogic)cls.newInstance();
         
// 调用execute方法,execute方法调用com.qujingbo.LoginUser类的doBusiLogic()方法         
         _AbstractLogic.execute(request, response);
      }

      
catch (java.lang.Exception cfe) 
      
{
         cfe.printStackTrace();
      }

   }

   
public   void  doGet(HttpServletRequest request, HttpServletResponse response)  throws  ServletException, IOException 
   
{
      doPost(request, response);
   }

}


给出它的
web.xml
<?xml version="1.0" ?>
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>
  
<welcome-file-list>
    
<welcome-file>index.jsp</welcome-file>
  
</welcome-file-list>

  
<servlet>
     
<servlet-name>FacadeServlet</servlet-name>
     
<servlet-class>FacadeServlet</servlet-class> 
    
<init-param>
      
<param-name>100</param-name>
    
<param-value>com.qujingbo.LoginUser</param-value>
    
</init-param>
</servlet>
    
<servlet-mapping>
        
<servlet-name>FacadeServlet</servlet-name>
        
<url-pattern>FacadeServlet</url-pattern>
    
</servlet-mapping>

</web-app>

下一步介绍AbstractLogic这个抽象类。该类包含两个方法。execute()方法调用抽象方法doBusiLogic()(其实是按配置具体实现类的doBusiLogic()方法)。有人会有疑惑为什么要用execute()调用doBusiLogic()方法呢?直接调用doBusiLogic方法不行吗?其实这里有个小技巧。就像filter一样,我们如果需要过滤些信息,只要写在execute()方法最开始就OK,这样,执行任意一个doBusiLogic()方法时,都会调用execute()方法。结束也一样。注释有说明。
package com.qujingbo;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
 * <p/> Title:
 * </p>
 * <p/> Description:
 * </p>
 * <p/> Date:2004-9-7 14:50:25
 * </p>
 * 
 * 
@author EOMS 曲静波
 * 
@version 1.0
 
*/

public abstract class AbstractLogic 
{
   
//模板模式,实现类需要实现doBusiLogic方法,在该方法中写业务逻辑
   public abstract void doBusiLogic(HttpServletRequest request, HttpServletResponse response) throws Exception ;
   
public void execute(HttpServletRequest request, HttpServletResponse response) throws Exception 
   
{
         
//若想在业务逻辑前执行某方法,写在这里
      
//System.out.println ("pre call");
      doBusiLogic(request, response);
      
//若想在业务逻辑后执行某方法,写在这里
         
//System.out.println ("post call");
   }

}


最后介绍要具体实现执行业务类LoginUserLoginUser继承AbstractLogic抽象类,实现doBusiLogic()方法。我们只需在doBusiLogic()方法内实现我们的业务逻辑就OKLogicUer中的doBusiLogic()方法模拟了一个登陆过程。

package com.qujingbo;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
import javax.rmi.PortableRemoteObject;
import loginEjbPac.LoginHome;
import loginEjbPac.Login;
/**
 * <p/> Title:
 * </p>
 * <p/> Description:
 * </p>
 * <p/> Date:2004-9-7 14:50:25
 * </p>
 * 
 * 
@author EOMS 曲静波
 * 
@version 1.0
 
*/

public class LoginUser extends AbstractLogic 
{
   
//实现登陆功能
   public void doBusiLogic(HttpServletRequest request, HttpServletResponse response) throws Exception 
   
{
      System.out.println(
"LoginUser");
      Context ctxt 
= null;
      ctxt 
= new InitialContext();
      DataSource ds 
= (DataSource)ctxt.lookup("jbPoolJndi");
      Connection con 
= ds.getConnection();
      Statement stmt 
= con.createStatement();
      ResultSet rs 
= stmt.executeQuery("select * from test");
      
//模拟登陆
      if(rs.next()) 
         System.out.println(rs.getString(
"name"));
      System.out.println(
"LoginEJB");
      LoginHome home 
= (LoginHome)PortableRemoteObject.narrow(ctxt.lookup("LoginEJBRemote"), LoginHome.class);
      Login remote 
= home.create();
      
if(remote.checkLoginUser("aa")) 
         System.out.println(
"EJB success");
      remote.remove();
   }

}


OK ,全部结束,我们重新理下顺序。首选通过 web.xml 配置 servlet FacadeServlet ),通过 url 访问 FacadeServlet ,以本实例为例, url 地址为 http://yourip:yourport/yourservlet?action=100 ,通过获取 action=100 ,在 web.xml 中取得对应的包名,类名。实例化它,由 FacadeServlet 调用 execute() 方法, execute 方法调用的是具体实例化类的 doBusiLogic() 业务方法。整个过程结束。

posted on 2006-10-16 19:34 曲静波 阅读(1657) 评论(1)  编辑  收藏 所属分类: design pattern

评论

# re: 使用façade、template pattern搭建MVC框架 2006-10-18 14:42 123bingbing

增开7群,号码 30440732
8群 30756649
9群 30178567
10群 28694497

我们的qq群:15096318 学习程序的都可以来
  回复  更多评论   


只有注册用户登录后才能发表评论。


网站导航:
 

导航

统计

常用链接

留言簿(3)

随笔分类(9)

随笔档案(8)

文章分类

友情链接

搜索

最新评论

阅读排行榜

评论排行榜