2.2 系统设计
系统设计的目的是产生一个可用的、完整的解决方案,并且能够比较容易地将方案转换成程序代码。这个阶段在三层结构的架构设计模型基础上,将考虑所有的实现技术问题,对分析阶段的模型进行扩展和细化,分析阶段定义的类进一步扩充,定义新的类来处理技术方面的问题,并形成最后的UML模型。
推动不断进行详细设计的方法是对每个用例进行动态建模,描述如何通过类图中的对象协作实现用例中的功能,由于一开始对系统的认识是很不够的,前面建立的类往往随着动态建模的深入,发现存在缺陷或不够完整,需要对分析中得到的域类图进行不断修正和调整,扩展形成业务逻辑包。同时,随着对用户界面、数据库访问等技术实现的深入建模,不断建立新的用户界面类(如窗体、控件)和数据访问类,形成用户界面包和数据访问包。
本学生管理系统经过详细设计后,在域类图基础上进行扩展后形成的业务逻辑包类图如下图4所示。
图3 域类图
图4 业务逻辑包类图
新建立的数据访问包类图如下图5所示。所有的数据访问类都定义了一个基类DBCommon,该基类包含属性 DBConnectionString,通过该属性可以获得数据库连接字符串。还包括一个方法GetDataView,可以实现在数据库中执行查询获得一个DataView。这些属性和方法被所有的数据访问类继承,可以直接使用。
图5 数据访问包
关于用户界面包的类图比较简单,主要是通过界面设计,设计出窗体及控件等界面元素,并根据动态建模时需要涉及的用户界面访问动作,定义所引起的相关事件,这些方面都在窗体类中进行定义,并组成用户界面包,这里就不详细介绍。
动态建模通常采用的方法是使用UML中的时序图描述用例,一个时序图针对某个用例中的一个“场景”进行分析。所谓“场景”是指一个用例中事件发展的一条路线。根据活动参与者的不同输入或行为,通常一个用例会有多个“场景”,也就需要分析出多个时序图。通过时序图描述一个场景中各个对象之间所进行的通信,同时可以分析出系统中相应的类需要具备的操作,从而不断扩充和细化类的设计。如果需要进一步描述类的状态变化情况和操作流程,可以使用UML中的状态图和活动图。
图6 登录场景
动态建模时产生的时序图较多,这里无法一一阐述。图6给出了登录系统场景的时序图,在用户界面包中定义了一个LoginForm类,其对应的Web窗体为用户登录窗体页面Login.aspx,图6描述了在该窗体中实现用户登录的场景。
2.3 基于ASP.NET的系统实现
前面系统设计动态模型时,通过时序图已经对每个用例的各项功能所涉及的场景进行了详尽的描述,按照时序图的规定把每个用例都分别进行编码实现即可。下面结合学生管理系统中的“登录系统”用例,介绍基于ASP.NET进行系统实现的方法。
首先需要考虑分包,ASP.NET中包对应的就是命名空间。在本学生管理系统中,规定业务逻辑包的命名空间为 ResultManage.BusinessRule,数据访问包的命名空间为ResultManage.DataAccess,而用户界面包的命名空间为ResultManage.Web。
然后进行业务逻辑包和数据访问包中相关类的设计,对于“登录系统”用例,从上图6的登录场景时序图中可以看出,相关的类有业务逻辑包的Users类和数据访问包的UsersDB类,分别对这些类的属性和方法进行定义和实现,并设计一些测试用例或测试程序对其进行单元测试。
最后按照用户界面包和上图6的登录场景时序图中的规定,对用户登录窗体页面Login.aspx进行设计实现,其实现登录的代码如下所示:
- private void btnLogin_Click(object sender, System.EventArgs e)
- {
- //获得用户登录信息
- string UserName = txbUserName.Text;
- string Password = txbPassword.Text;
- try
- {
- if (Users.Login(UserName , Password)) //检查用户登录信息
- {
- //创建身份验证票
- FormsAuthentication.SetAuth(UserName, false);
- //显示欢迎信息
- ShowWelcomeMessage(UserName);
- }
- else
- {
- Message.Text = "用户登录失败!";
- }
- }
- catch (SqlException sqlexception)
- {
- //提示数据库操作错误信息51aspx.com
- Response.Write(sqlexception.Message);
- }
- }
- 代码中对于业务的处理,通过调用业务逻辑包Users类的Login方法实现登录信息的检查,其代码如下:
- public static bool Login(string UserName , string Password)
- {
- if (UserName == "")
- {
- return false;
- }
- else
- {
- //检查数据库中是否存在符合的用户
- return UsersDB.CheckLogin(UserName , Password);
- }
- }
复制代码上述Users类的Login方法的代码中,首先进行业务逻辑检查,判断用户名是否为空,涉及数据库访问则通过数据访问类完成,通过数据访问包的UsersDB类的CheckLogin方法从数据库中检查是否存在符合相应登录信息的用户。
前面已经提到,包括UsersDB类在内的数据访问层所有类都从一个基类DBCommon继承,该基类封装了所有数据库访问类公共的特性,其中包括定义了公共属性:数据连接字符串DBConnectionString。UsersDB类的CheckLogin方法中使用 DBConnectionString进行数据库的连接,并调用数据库中存储过程CheckLogin查找用户登录信息是否正确。
3 结束语
本文介绍了三层B/S结构系统的UML建模和基于ASP.NET进行实现的过程和方法,实现的三层结构不仅程序逻辑上结构清晰,而且由于容易发生需求变更的业务逻辑部分实现了分离,因此具有更强的可扩展性和可维护性。同时这种系统在部署时具有很强的灵活性,可以将各个包分别编译成.NET组件,安装在多台服务器。较典型的是用户界面包安装在Web服务器,业务逻辑包安装在应用服务器,数据访问包安装在数据库服务器或进一步分离,从而实现多级分布的部署方式,实现更好的可伸缩性和安全性,满足大规模的企业级B/S应用系统的需求。
参考文献
1 Frank Buschmann, Regin Meunier, Hans Rohnert et al. Pattern-Oriented Software Architecture[M]. New York: John Wiley & Sons Ltd, 1996.1~50
2 T.J. Popp. Software Architecture Development for Produce Line Software[A]. Proceedings of the 18th IEEE Digital Avionics Systems Conference[C]. USA:IEEE Computer Society Press, 1999. 106~111
3孙昌爱,金茂忠,刘超. 软件体系结构研究综述. 软件学报[J],2002,13(7):1228~1237
收稿日期:4月17日 修改日期:4月30日