在我们利用PB进行MIS系统开发时,有很多业务是通用的,并且有很多组件是可以复用的。为了提高MIS系统的开发效率,缩短开发周期,有必要把一些公用对象抽象出来,以便作二次开发。 这些通用的对象,一部分是针对基本功能进行扩充的,我叫它通用类库,采用加ufc_前缀的方式命名, 一部分是针对业务功能进行扩充的,采用加wfc_前缀的方式命名。 以下先从整体上描述整个类库的框架, 然后在从具体的类库来描述各个模块。
一、数据库框架 我们假定现在有两个MIS系统需要开发,分别是"应用系统1"和"应用系统2",其中应用系统1中有两年的数据,分别是年份1和年份2。为了实现系统功能的同一管理和代码在最大可能的重用,我们设计了整个系统的数据库框架:

如上图,我们分别对应用系统1的年份1和年份2以及应用系统2分别建立三个数据库: A1、A2和B。如果还有更多的应用系统的话,我们都可以建立更多的数据库与之对应。 这里,为什么应用系统1中年份1和年份2要建立两个数据库呢?由于很多MIS系统中,每自然年或者逻辑年后,系统的数据库都需要进行备份和封存,上一年的数据库一般就不允许再进行修改操作。这样,我们可以建立一个新的数据库来存放新一年的数据,应用软件可以在不进行任何修改的情况下实现多年数据的管理,并且能保证数据量不会过分膨胀。 把应用系统的数据库按年份来管理后,就产生了权限管理、数据库连接、数据库结转等问题,为了实现系统权限、用户等的统一管理,我们不在每一个具体的和业务有关的数据库中建立相关的表,而是再建立一个系统数据库S,通过它来对应用系统数据库进行连接和管理。在这个数据库中,一般包括以下表:系统用户表(User)系统角色表(Role),系统权力表(Power),角色模块权力表(RoleRPower),用户模块权力表(UserRPower),用户角色表(UserRRole),系统模块表(Module),系统对象表(Object),模块对象表(ModuleRObject)等权限管理表,为了实现其它一些通用的系统管理功能,还有一些通用的表,主要是:系统参数表(SysParm),系统字典表(SysTypeInfo),系统序列号表(SysSequence),表属性表(SysTable), 列属性表(SysColumn),系统消息表(SysMsg) ,历史表(HisTbl),事件日志表(EventLog),书签表(BookMark),系统程序表(Program),帐套表(AccountSet)等等。 数据库这样一改造后,权限管理分成了两部分,数据库权限管理和应用系统权限管理, 数据库权限管理通过数据库管理系统本身提供的功能来设置,应用系统权限通过应用程序来设置, 同时我们的应用程序也要改造了, 应用系统首先连接系统数据库S, 根据其连接的身份决定是否进行数据库管理(创建和维护帐套以及备份数据库等)还是连接业务系统,如果连接用户是系统数据库S的管理员,则打开数据库管理界面。 如果只是系统数据库S的普通操作员,则从S的帐套表中读出帐套信息,显示业务系统登录对话框,根据输入的业务系统连接身份以及选择的帐套,连接业务数据库A1或A2,连接成功后,根据其在业务系统中定义的权限(UserRight表)来决定其下一步的方向, 是打开业务系统管理界面,还是业务系统操作界面。 我们看看改造后的系统登录流程:
数据库这样改造后,系统的安全性获得了极大的提高,对于数据库管理员有至高无上的权力,它可以创建系统数据库S的连接用户,赋予其普通的数据库连接权限和对帐套表的 SELECT权限, 它连接上系统数据库S后,可以创建帐套(即业务数据库),设置其数据库连接参数:用户名和密码等, 这些连接参数可以不必透露给业务系统管理员,而只需把在系统数据库S上创建的普通连接账号告诉业务系统用户就行了。 业务系统用户利用此账号来连接系统数据库S,然后从帐套表中取出所有的有效帐套,弹出业务系统登录对话框, 选择一个帐套以及业务系统的登录用户名与密码,进行登录,系统首先必须根据帐套获取此帐套实际连接的数据库以及登录的用户名与密码,假如我们是选择了A2, 利用表中设置的用户名和密码(当然是加过密的喽),连接A2数据库,然后从系统用户表(User)中检验其系统用户身份,通过后,才能登录到系统中。 这样,系统就建立了对两个数据库的连接。
除此之外,如果考虑到业务系统的本地化、个性化,在C/S构架下,我们可以再在每个业务系统的本地自动创建一个文件型数据库,一般可以采用Access和SQLAnyWhere来实现,也可以采用自己的格式来定义。在其中可以创建一些通用表:个性化表(Preference),方案表(Scheme),语言表(Language)等。 这样构架后, 一个MIS系统的数据就由三个数据库组成, 系统中必须保持对这三个数据库的连接, 在PB中,我采用了三个事务连接来管理,分别为:SQLSys, SQLCom , SQLLoc。
接下来,将在这个数据库架构下,进行通用类库搭建。
二、UFC通用类库框架 (一)UFC通用类库简介 UFC(User Foundation Class)类库是一组PowerBulider的对象,它是由许多通用对象组成的基础类库。主要包括权限管理对象、错误截获对象、应用程序管理对象、事务管理对象、数据窗口服务对象、窗口对象等。 类库主要包括以下几个包: 1、五个核心包 UFCAppSrv.pbl 应用对象服务包,包括应用程序管理对象、字符串操作对象、数值操作对象等。 UFCMain.pbl 通用对象服务包, 包括PB的标准对象的各种扩展对象:窗口、数据窗口、编辑框、图片按钮等。 UFCObjSrv.pbl 定制对象服务包, 大部分是一些定制的用户对象,例如工具条、OutLook条等。 UFCDwSrv.pbl 数据窗口服务包,包括各种数据窗口服务,例如过滤服务、查找服务、排序服务、弹出菜单服务等。 UFCWnSrv.pbl 窗口服务包,包括数据窗口上的扩展服务,例如状态条服务、个性化风格服务等。 2、两个辅助包 UFCTemplate.pbl 模板对象包, 包括各种模板窗口。 UFCCommon.pbl 公共业务对象包, 包括MIS系统的一些通用业务窗口和数据窗口,例如权限管理窗口、系统参数管理窗口等。 3、可选包(可以根据需要包含) UFCExternal.pbl 外部扩展对象包,包括各种第三方PB对象,以及API相关对象。 UFCDatabase.pbl 数据库对象包,包括对各数据库对象的统一封装,以及业务帐套的管理。 4、工具包(可以根据需要包含) UFCReport.pbl 通用报表对象包,提供了一个通用的报表工具。 UFCUpdate.pbl 自动升级对象包,提供了一个最新程序上载和更新的工具。 UFCStatistic.pbl 通用数据统计分析图表包,提供通用的对数据的统计和分析工具,以及图表显示。 (二)UFC通用类库命名规范 1、UFC对象的命名 所有基础类库的对象(包括所有的结构体和全局函数), 其名称都带前缀ufc_,加上这个前缀的好处是让业务对象与类库对象区别开来, 而不会产生重名的麻烦: ufc_type_objectname 具体类型说明如下: 前缀 描述 ufc_m_ Menu ufc_n_ Standard class user object ufc_n_ Custom class user object ufc_s_ Global structure ufc_u_ Visual user object ufc_w_ Window
例如: 例子 解释 ufc_w_base 所有窗口的基类 ufc_u_tv TreeView控件基类 ufc_u_dw DataWindow控件基础类 ufc_n_dwsrv 数据窗口服务基础类 ufc_n_tr 不可视的事务对象基础类
2、UFC对象实例命名 所有对象实例采用PB中标准的命名方式, 采用(对象类型缩写)+(_)+(实例英文描述) 例如: dw_Master , w_Logon 等。
3、UFC变量命名 所有变量和PB中默认的命名方式一致, 采用 (作用域)+(类型)+(_)+(变量英文描述) 例如: gnv_App li_Index is_UserName 等。
4、UFC基础类库中事件和函数命名 所有自定义事件(非系统事件), 都采用 (ufc_)+(事件描述)的方式, 例如: ufc_Open 对于一个事件的前触发和后触发, 采用(ufc_Pre)+(事件描述)表式前触发, 采用(ufc_Post)+(事件描述)表示后触发, 例如: ufc_PreOpen , ufc_PostOpen。 对于函数, 采用 (of_)+(函数描述)的方式, 例如 of_GetUserName() 。
(三)核心包分析 UFC基础类库主要采用窗口、标准用户对象、定制用户对象来实现面向对象封装。主要的服务有: 1、应用程序管理对象(ufc_n_AppManage),实现整个应用程序的管理,以及对应用系统全局变量的封装。它包含的服务主要有: A。系统参数对象(ufc_n_SysParam),提供了对业务系统数据库中的各种全局参数的访问。 B。错误日志对象(ufc_n_Error), 提供了对系统中各种错误的捕获,最后统一记录和显示出错信息。 C。事件日志对象(ufc_n_EventLog),提供了每个系统登录用户的登录细节,以及对系统的操作情况。 D。系统序列号对象(ufc_n_Sequence), 提供定义系统中各种编号的规则定义,以及各种编号的自动生成。 E。权限管理对象(ufc_n_RightManage), 提供了一个统一的权限管理对象,通过它来获取登录用户对每个模块的访问权限(ufc_n_Right),所有权限感应对象根据传递给它的ufc_n_Right来初始化其自身表现。
2、窗口对象和窗口服务对象 主要的几个窗口基类说明: ufc_w_base --是所有窗口的基类,封装了一些与业务无关的通用功能。 -ufc_w_master --为了扩展一些API效果,在UFCMain.PBL或UFCExternal.PBL中实现。 --ufc_w_frame --MDI窗口基类 ---ufc_w_navigateframe --导航式的MDI窗口模板 --ufc_w_main --业务窗口基类,实现了与数据窗口的关联和事件映射。 ---ufc_w_sheet --业务子窗口 --ufc_w_popup --Popup风格窗口基类 --ufc_w_response --Response风格窗口基类 主要的窗口服务有: A。状态条服务, 为PB中的MDI窗口提供多功能的状态提示条。 B。工具条服务, 提供对PB中的标准工具条的操作界面。 C。桌面配置服务, 对应用程序的整体外观进行配置,包括导航条、状态条、工具条的开关,窗口位置的保存等。 D。墙纸服务,提供在应用程序的MDI区显示背景图片。 E。个性化偏爱服务, 提供了对窗口配置的自动读取和设置。
3、数据窗口对象和数据窗口服务 整个基础类库就是对数据窗口的扩展,为了不导致数据窗口对象的过度膨胀,把各种服务功能独立成一个服务对象,而在数据窗口中采用引用服务对象的方式来实现。 其中主要的数据窗口服务有: A。排序服务(ufc_n_dwsrv_sort) B。过滤服务(ufc_n_dwsrv_filter) C。查询服务(ufc_n_dwsrv_query) D。检索服务(ufc_n_dwsrv_retrieve) E。自动保存服务(ufc_n_dwsrv_autosave) F。数据导出服务(ufc_n_dwsrv_export) G。数据导入服务(ufc_n_dwsrv_import) H。下拉查找服务(ufc_n_dwsrv_dropdownsearch) I。链接服务(ufc_n_dwsrv_linkage) J。多表服务(ufc_n_dwsrv_multitable) K。弹出菜单服务(ufc_n_dwsrv_PopMenu) L。弹出选择服务(ufc_n_dwsrv_PopSelect) M。行管理服务(ufc_n_dwsrv_rowmanage) N。行选择服务(ufc_n_dwsrv_rowselect) O。重复列判断服务(ufc_n_dwsrv_repeate) P。要求列判断服务(ufc_n_dwsrv_Required) Q。初始化列服务(ufc_n_dwsrv_initcolumn) R。改变大小服务(ufc_n_dwsrv_resize) S。日历服务(ufc_u_Calendar) T。计算器服务(ufc_u_Calculate) U。错误记录服务(ufc_n_error) V。弹出按钮服务(ufc_u_PopButton)
4、全局服务对象 主要有以下服务对象: A、字符串操作对象(ufc_n_String) --包括对字符串的分割、全局替换等。 B、日期时间操作对象(ufc_n_DateTime) --包括对日期时间的增减、日期字符串的转换等。 C、数值操作对象(ufc_n_Numerical) --包括对数值的转换,包括金额的大小写转换等。 D、类型转换对象(ufc_n_Conversion) --提供对各种枚举与基本类型之间的转换。 E、平台对象(ufc_n_PlatForm) --提供对操作系统平台的支持。 F、SQL对象(ufc_n_SQL) --对SQL语句进行解析和拆分 |