mvc三层构架在asp中的应用
2010年2月13日
前段时间读了不少关于MVC的文章,试着在ASP中应用了一下,发现对于小程序,代码量会大幅度增加,但是逻辑清晰,数据封装很合理,以前需要仔细规划的代码复用竟然成了理所当然的事情。
所谓MVC,即Model(模型),View(视图),Control(控制)三层架构。各部分各司其职,Model即底层构架,包含与数据库连接的部分,View即UI展示部分,与用户直接打交道,Control即控制层,负责接收View的请求并做适当预处理后交由Model处理,然后接收Model返回值并做格式化处理返回View层。简单地说,Model直接与系统底层如数据库等打交道,而不管数据出去后如何用,View只负责请求和展示数据,而不管详细流程,Control分别与View和Model打交道,并负责数据的验证、格式化等工作。
写了一个获取用户资料的ASP中应用:
先写Model层,定义数据库地址,打开连接数据库,获取记录。
在写Model层之前定义了两个类:Cls_Config整站设置,包括数据库地址;Cls_DatabaseModel,负责打开关闭数据库连接。
Cls_ConfigModel.asp代码如下:
<%
Class Cls_ConfigModel
Private i_datapath,i_sitename,i_sitedomain,i_mastermail
Private Sub Class_Initialize()
i_datapath="data\testtdata.mdb"
i_sitename="testsite"
i_sitedomain="www.test.cn"
i_mastermail="master@test.cn"
End Sub
Public property get DataPath
DataPath=server.MapPath(i_datapath)
End property
Public property get SiteName
SiteName=i_sitename
End property
Public property get SiteDomain
SiteDomain=i_sitedomain
End property
Public property get MasterMail
MasterMail=i_mastermail
End property
End Class
%>
<%
Class Cls_ConfigModel
Private i_datapath,i_sitename,i_sitedomain,i_mastermail
Private Sub Class_Initialize()
i_datapath="data\testtdata.mdb"
i_sitename="testsite"
i_sitedomain="www.test.cn"
i_mastermail="master@test.cn"
End Sub
Public property get DataPath
DataPath=server.MapPath(i_datapath)
End property
Public property get SiteName
SiteName=i_sitename
End property
Public property get SiteDomain
SiteDomain=i_sitedomain
End property
Public property get MasterMail
MasterMail=i_mastermail
End property
End Class
%>
Cls_DatabaseModel.asp代码如下:
<!--#include file="cls_configmodel.asp" -->
<!--#include file="../public/cls_cache.asp" -->
<%
Class Cls_DatabaseModel
Private i_config,i_cache,i_datapath
Private i_conn
Private Sub Class_Initialize()
set i_cache = new Cls_Cache
if i_cache.GetCache("Config","DataPath") = "" then
set i_config = new Cls_ConfigModel
i_datapath = i_config.DataPath
Call i_cache.SetCache("Config","DataPath",i_datapath)
else
i_datapath = i_cache.GetCache("Config","DataPath")
end if
set i_cache = nothing
End Sub
Private Sub Class_Terminate()
set i_config=nothing
End Sub
Public property get Conn
set Conn=i_conn
End property
Public Function OpenConn()
set i_conn=server.createobject("adodb.connection")
i_conn.open "Provider=Microsoft.Jet.OLEDB.4.0;Data Source="& i_datapath &";User ID=admin;Password=;Jet OLEDB:Database Password="
End Function
Public Function CloseConn()
set i_conn=nothing
End Function
End Class
%>
<!--#include file="cls_configmodel.asp" -->
<!--#include file="../public/cls_cache.asp" -->
<%
Class Cls_DatabaseModel
Private i_config,i_cache,i_datapath
Private i_conn
Private Sub Class_Initialize()
set i_cache = new Cls_Cache
if i_cache.GetCache("Config","DataPath") = "" then
set i_config = new Cls_ConfigModel
i_datapath = i_config.DataPath
Call i_cache.SetCache("Config","DataPath",i_datapath)
else
i_datapath = i_cache.GetCache("Config","DataPath")
end if
set i_cache = nothing
End Sub
Private Sub Class_Terminate()
set i_config=nothing
End Sub
Public property get Conn
set Conn=i_conn
End property
Public Function OpenConn()
set i_conn=server.createobject("adodb.connection")
i_conn.open "Provider=Microsoft.Jet.OLEDB.4.0;Data Source="& i_datapath &";User ID=admin;Password=;Jet OLEDB:Database Password="
End Function
Public Function CloseConn()
set i_conn=nothing
End Function
End Class
%>
其中Cls_Cache是一个缓存类,这里缓存了数据库地址。
用户Model层Cls_UserModel.asp代码如下:
<!--#include file="cls_databasemodel.asp" -->
<%
Class Cls_UserModel
Private i_database,i_sql,i_rs
Public UserInfo()
Private Sub Class_Initialize()
set i_database=new Cls_DatabaseModel
End Sub
Private Sub Class_Terminate()
set i_database=nothing
End Sub
Public Function GetUserInfo(KeyType,Key)
select case KeyType
case "uid"
i_sql="select * from [MYT_User] where UserId=" & Key
case "uname"
i_sql="select * from [MYT_User] where UserName='" & Key & "'"
end select
i_database.OpenConn()
set i_rs = i_database.Conn.execute(i_sql)
if not i_rs.eof then
ReDim UserInfo(i_rs.fields.count)
for i=0 to i_rs.fields.count-1
UserInfo(i)=i_rs(i)
next
else
ReDim UserInfo(2)
UserInfo(0)=0
UserInfo(1)="guest"
End if
i_rs.close
set i_rs=nothing
i_database.CloseConn()
End Function
End Class
%>
<!--#include file="cls_databasemodel.asp" -->
<%
Class Cls_UserModel
Private i_database,i_sql,i_rs
Public UserInfo()
Private Sub Class_Initialize()
set i_database=new Cls_DatabaseModel
End Sub
Private Sub Class_Terminate()
set i_database=nothing
End Sub
Public Function GetUserInfo(KeyType,Key)
select case KeyType
case "uid"
i_sql="select * from [MYT_User] where UserId=" & Key
case "uname"
i_sql="select * from [MYT_User] where UserName='" & Key & "'"
end select
i_database.OpenConn()
set i_rs = i_database.Conn.execute(i_sql)
if not i_rs.eof then
ReDim UserInfo(i_rs.fields.count)
for i=0 to i_rs.fields.count-1
UserInfo(i)=i_rs(i)
next
else
ReDim UserInfo(2)
UserInfo(0)=0
UserInfo(1)="guest"
End if
i_rs.close
set i_rs=nothing
i_database.CloseConn()
End Function
End Class
%>
Model层构造SQL语句并查询,然后将记录集存入UserInfo数组,供Control层调用。
Control层Cls_User.asp代码如下:
<!--#include file="../model/cls_usermodel.asp" -->
<%
Class Cls_User
Private i_uid,i_uname,i_user
Private Sub Class_Initialize()
set i_user = new Cls_UserModel
End Sub
Private Sub Class_Terminate()
set i_user=nothing
End Sub
Public property get Uid
Uid=i_uid
End property
Public property get UName
Uname=i_uname
End property
Public property let Uid(Userid)
i_uid=Userid
Call i_user.GetUserInfo("uid",Userid)
FillInfo()
End property
Public property let UName(UserName)
i_uname=UserName
Call i_user.GetUserInfo("uname",UserName)
FillInfo()
End property
Private Function FillInfo()
i_uid=i_user.UserInfo(0)
i_uname=i_user.UserInfo(1)
End Function
End Class
%>
<!--#include file="../model/cls_usermodel.asp" -->
<%
Class Cls_User
Private i_uid,i_uname,i_user
Private Sub Class_Initialize()
set i_user = new Cls_UserModel
End Sub
Private Sub Class_Terminate()
set i_user=nothing
End Sub
Public property get Uid
Uid=i_uid
End property
Public property get UName
Uname=i_uname
End property
Public property let Uid(Userid)
i_uid=Userid
Call i_user.GetUserInfo("uid",Userid)
FillInfo()
End property
Public property let UName(UserName)
i_uname=UserName
Call i_user.GetUserInfo("uname",UserName)
FillInfo()
End property
Private Function FillInfo()
i_uid=i_user.UserInfo(0)
i_uname=i_user.UserInfo(1)
End Function
End Class
%>
Cls_User类中只定义了两个属性:i_uid,i,uname。当View层给i_uid或者i_uname赋值的时候调用Model层查询用户信息,然后用Fillinfo函数填写属性供View层调用。
View层UserInfo.asp代码如下:
<!--#include file="control/cls_user.asp" -->
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312" />
<title>显示用户信息</title>
</head>
<body>
<%
set User=new Cls_User
for iii=1 to 100
User.Uid=2
response.write User.Uid
response.write User.UName
next
set User=nothing
%>
</body>
</html>
<!--#include file="control/cls_user.asp" -->
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312" />
<title>显示用户信息</title>
</head>
<body>
<%
set User=new Cls_User
for iii=1 to 100
User.Uid=2
response.write User.Uid
response.write User.UName
next
set User=nothing
%>
</body>
</html>
这样调用逻辑就非常清晰了。
试着加了一个循环(注释掉的代码),查询100个用户大约要3秒左右,看来频繁连接数据库开销确实很大。
另外,循环的时候变量不能用i,不然只能显示第一个用户信息,不知何故。
三层构架的大致思想基本算是掌握了,缓存应用还不够自如,模板类的实现还没开始。任重道远。
PS:今天大年三十,祝所有人幸福安康!