扫一扫
分享文章到微信
扫一扫
关注官方公众号
至顶头条
作者:佚名 来源:动网先锋 2007年11月8日
关键字: Windows
2、建立动态链接库
启动VB(这里以VB为例,你可以用你喜欢的任何支持ActiveX接口的开发工具开发),新建一工程,工程类型为ActiveX DLL。在工程中新建一个类,取名为Employee。你可以Class Builder可视化的向类中填加属性和方法,也可以直接手工编辑。首先填加EMPLID属性如下:
Private msEMPLID as string
Property Let EMPLID(sEMPLID as string)
msEMPLID=sEMPLID
End Property
Property Get EMPLID() as string
EMPLID=msEMPLID
End Property
一般地讲,每一个属性都应该有Property Let和Property Get两个方法,它们分别当向属性赋值和读取属性值时被调用。如果某个属性只被赋值而从不被读取(这种情况多发生在对应数据库表的主键的属性上),则Property Get方法可以省略。Property Let方法不能省略。你可以仿照上面的程序再建立Name,Gender和Score三个属性。然后创建如下方法:
Public Sub Create(EMPLID as string)
dim conn as new Connection
dim rs as new Recordset
dim sql as string
'Suppose that you create a DSN in the control panel, the connectionstring property
'can also be dsn-less string
conn.ConnectionString="dsn=dsnname;uid=username;password=pwd"
conn.open
sql="select * from Employee where EMPLID='" & EMPLID & "'"
with rs
.open sql,conn,1,3
if .eof and .bof then
exit sub
else
msEMPLID=trim(.Fields("EMPLID"))
msName=trim(.Fields("Name"))
msGender=trim(.Fields("Gender"))
msScore=.Fields("Score")
end if
.close
end with
set rs=nothing
conn.close
set conn=nothing
End Sub
这里根据EMPLID创建Employee对象,注意数据库中的值是赋给三个私有变量,而不是直接赋值给属性,如果你单步调试就会发现,给msEMPLID赋值会调用Property Let EMPLID,也就是给属性赋值。
下面我们再创建一个类Employees,并填加如下方法:
private colQualifiedList as new Collection
private mnCurrentIndex as integer
Public Sub GetQualifiedList()
dim conn as new Connection
dim rs as new Recordset
dim sql as string
'Suppose that you create a DSN in the control panel, the connectionstring property
'can also be dsn-less string
conn.ConnectionString="dsn=dsnname;uid=username;password=pwd"
conn.open
sql="select EMPLID from Employee where Score>=60 order by Score desc"
with rs
.open sql,conn,1,3
if .eof and .bof then
exit sub
else
do while not .eof
dim oEmployee as new Employee
oEmployee.Create trim(.Fields("EMPLID"))
colQualifiedList.Add oEmployee
set oEmployee=nothing
loop
end if
.close
end with
set rs=nothing
conn.close
set conn=nothing
End Sub
首先请注意VB中创建类实例的语法dim oEmployee as new Employee,后面会看到,在ASP中创建类实例的语法是不同的。这个方法检索成绩大于等于60的员工工号,并据此创建一个Employee对象,再将此对象加入私有的集合对象中。下面两个函数遍历集合中的元素:
Public Function GetFirst() as Employee
if colQualifiedList.count>0 then
mnCurrentIndex=1
set GetFirst=colQualifiedList.Item(1)
else
set GetFirst=nothing
end if
End Function
Public Function GetNext() as Employee
mnCurrentIndex=mnCurrentIndex+1
if mnCurrentIndex>colQualifiedList.count then
set GetNext=nothing
else
set GetNext=colQualifiedList.Item(mnCurrentIndex)
End if
End Function
也许你会说,为何不把集合声明Public,这样在ASP中不是可以直接引用吗?确实,这样也行得通,编程实现起来也更简单些,但是,这样做破坏了封装性原则。因为数据以何格式存储完全是商业逻辑层的事,与用户界面层无关,假设有一天你因为每种原因放弃了用集合来存储数据的设计,而改用数组或记录集(Recordset)来存储,那你只需要修改GetFirst和GetNext两个函数,用户界面层完全无需修改。
至此类文件创建完毕,将工程文件存为 test.vbp,选File菜单下的Make test.dll选项将其编译。
3、注册动态链接库
启动Web Server 上的Microsoft Transaction Server (Start--Windows NT Optionpack4--Internet Information Server--Internet Service Manager),展开Microsoft Transaction Server--Computer--My Computer--Package Installed,点鼠标右键选New--Package--Create Empty Package,输入包名Test(这里Test是任选的名字,不一定要与DLL同名),OK-Interactive User-the current Logon user--Finish。双击Test--Component,右键选Component-New-Component-Install New component(s)-- Add File,选择你刚编译好的DLL文件,MTS会发现DLL中有两个类Employee和Employees。至此DLL注册完毕。
4、编写ASP程序
<HTML><Body>
<p>Qualified Employee List</p>
<table border=1 cellspacing=0 cellpadding=0>
<tr>
<td>Employee ID</td>
<td>Name</td>
<td>Gender</td>
<td>Score</td>
</tr>
<%
set oEmployees=server.createobject("Test.Employees")
oEmployees.GetQualifiedList
set oEmployee=oEmployees.GetFirst()
do while not oEmployee is nothing
%>
<tr>
<td><%=oEmployee.EMPLID%></td>
<td><%=oEmployee.Name%></td>
<td><%=oEmployee.Gender%></td>
<td><%=oEmployee.Score%></td>
</tr>
<%
set oEmployee=oEmployees.GetNext()
loop
%>
</table>
</body></html>
注意在ASP中创建类实例的语法set oEmployees=server.createobject("Test.Employees"),其中Test是DLL的名字,Employees是类的名字; 当然,如果一个函数的返回值是一个对象,类似set oEmployee=oEmployees.GetFirst()这样的语法也是可以的。
至此,一个完整的三层结构的应用程序已经完成了,让我们看以下,如果把"合格"的定义改为:只有成绩进入前100名才算合格,程序需要做那些修改。事实上,如果你的数据库系统是SQL Server,你只需把SQL语句改为: sql="select top 100 EMPLID from Employee order by Score desc" 就已经可以了,即使为了跨数据库系统的兼容性,我们也只需要对GetQualifiedList做如下修改:
sql="select EMPLID from Employee order by Score desc"
with rs
.open sql,conn,1,3
if .eof and .bof then
exit sub
else
i=1
do while (not .eof) and (i<=100)
dim oEmployee as new Employee
oEmployee.Create trim(.Fields("EMPLID"))
colQualifiedList.Add oEmployee
set oEmployee=nothing
i=i+1
loop
end if
.close
end with
...
然后把DLL重新编译,注册就可以了,ASP程序完全不必修改。
四、一些说明和注意事项
1、 由于这个例子比较简单,在Employee类中可以没有Create方法,而在Employees类中将员工的所有信息(工号,姓名,性别,成绩)都读出来并将其赋给Employee对象对应的属性。但在实际应用中,当Employee对象的属性增多,或表的数量增多,表之间关系变复杂时,还是本文所示的方法更有效,代码重用的机会更大。
2、当DLL被修改后,在MTS中只能将其删除后重新注册,因为每次重新编译后在注册表中对象的ID值都将重新生成。
3、从ASP中调用带参数的类方法和函数时,所有的变量参数一定要用相应的类型转换函数转换后再传入,否则会引起类型不匹配错误,因为VBScript中只有Variant类型,它不能自动转换成其它类型。例如,有如下的函数定义:
Public Function Fun1(p1 as string,p2 as integer) as integer
End Function
在ASP程序中应如下调用:
<%
p1=obj.property1 ' Property1 is a string property
p2=obj.property2 'Property2 is an integer property
a=obj.Fun1(cstr(p1),cint(p2))
a=obj.Fun1("aaa",10) ' constant parameter need not be changed
%>
而下面的两种写法是错误的:
<%
p1=obj.property1 ' Property1 is a string property
p2=obj.property2 'Property2 is an integer property
a=obj.Fun1(p1,p2) ' incorrect,p1 and p2 are variant variables
p1=cstr(p1)
p2=cint(p2)
a=obj.Fun1(p1,p2) ' still incorrect
%>
这里第二种写法仍然是错误的,即使经过了类型转换,p1和p2仍然是Variant变量。在VBScript中,数据类型和类型转换函数只在表达式运算中起作用,变量只有Variant一种类型。
结束语
以上对多层结构的理论和实践进行了一番探讨,希望能对您的开发有所帮助。这里还有一个问题,即类和类的成员该如何设计。这既涉及面向对象编程的理论,也需要一定的实践经验。请参考相关的OOP理论书籍并在实践中不断总结,相信您一定能设计出自己的完美的多层结构的应用程序。
如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。
现场直击|2021世界人工智能大会
直击5G创新地带,就在2021MWC上海
5G已至 转型当时——服务提供商如何把握转型的绝佳时机
寻找自己的Flag
华为开发者大会2020(Cloud)- 科技行者