软件开发的过程就是一个不断分类总结的过程,软件开发应该遵循代码简单易读,结构清晰明了。新手的问题在于不知该如何分类,总是一股脑的将代码写在主窗体,在按钮的事情里写大量的代码,不区分界面展示,业务逻辑,业务数据和数据库操作。
开发过程中最常见的业务如对一个数据表内容的增,删,改,将数据放在一个ListView中。很多人都会直接将ADO控件直接放在主窗体,然后在按钮事件里就开始查询表,得到数据级后,直接在数据集的循环里就开始向表格添加了,按钮事件里代码老长。
这个功能应该分成三个部分:数据库操作,业务对象管理,界面显示。
如表中数据是一个用户清单 TUserInfo
先创建一个业务类:TUserInfo,然后创建一个业务类容器TUserInfoList
将ADOConnection ,ADOQuery 都放在TDataModule 里,然后给TDataModule添加
function GetList(AList:TUserInfoList):Integer;
function Delete(AID:Integer):Integer;
function Save(AUserInfo:TUserInfo):Boolean; 这几个方法。 主界面实现
procedure UserInfoToListItem(AItem:TListItem;AUserInfo:TUserInfo);将一行数据显示到表格
procedure UserInfoListToListView(AList:TUserInfoList;LV:TListView);//显示列表到表格
procedure LV_DeleteUserInfo;实现将选中的行删除
然后主界面放置 TActionList,添加对应的:新建,删除,修改的方法。
然后按钮设置 Action 这样的应用是属于同步应用的,开发要容易一些,只是分成几块后程序结构会比较清晰易读一些。
开发过程中最常见的业务如对一个数据表内容的增,删,改,将数据放在一个ListView中。很多人都会直接将ADO控件直接放在主窗体,然后在按钮事件里就开始查询表,得到数据级后,直接在数据集的循环里就开始向表格添加了,按钮事件里代码老长。
这个功能应该分成三个部分:数据库操作,业务对象管理,界面显示。
如表中数据是一个用户清单 TUserInfo
先创建一个业务类:TUserInfo,然后创建一个业务类容器TUserInfoList
将ADOConnection ,ADOQuery 都放在TDataModule 里,然后给TDataModule添加
function GetList(AList:TUserInfoList):Integer;
function Delete(AID:Integer):Integer;
function Save(AUserInfo:TUserInfo):Boolean; 这几个方法。 主界面实现
procedure UserInfoToListItem(AItem:TListItem;AUserInfo:TUserInfo);将一行数据显示到表格
procedure UserInfoListToListView(AList:TUserInfoList;LV:TListView);//显示列表到表格
procedure LV_DeleteUserInfo;实现将选中的行删除
然后主界面放置 TActionList,添加对应的:新建,删除,修改的方法。
然后按钮设置 Action 这样的应用是属于同步应用的,开发要容易一些,只是分成几块后程序结构会比较清晰易读一些。
解决方案 »
- 报表打印
- 请问如何将数据库中所有表的结构(包括字段类型、是否索引、是否允许为空)等信息写入到一个XML文档中?
- Delphi这么少人用吗?
- 大家好,请问fastreport的预览窗口在打开时如何刷新?
- 【一个简单的水晶报表问题!!!!!!】
- 急寻CRC32校验dll?
- 大虾帮忙看看http://expert.csdn.net/Expert/topic/2556/2556311.xml?temp=1.432437E-02
- 我用xpmenu,为什么其它控件都能有xp风格,但是主菜单没有xp风格?在编辑时,可以看到主菜单有xp风格,但是运行的时候就没有
- 请教高手如何做一个三层结构的数据库系统?
- DELPHI6支持ADO/MD吗?
- 变量名的问题
- 多线程写数据库,虚拟内存不断增长
用一个就可以了,否则会造成图片重复,编译后的程序变大,TImageList如果放置的是16*16的图标,则命名为
img_1616。5.TDataModule 一般命名为 DMApp,做为系统中主要的一个公用单元。放置一些TADOConnection ADOQuery等非可初控件。6.所有的按钮事件都使用 TActionList 如有用户添加,用户删除的功能,创建 act_UserAdd,act_UserDelete这些对应的 TAction。引用 DMApp单元的 img_1616给每个 TAction 设置图标。7.按钮功能,右键菜单,工具栏都指定自己的 Action属性。8.如果某个地方需要指定调用一个功能,如要调用刷新,来重新显示用户清单,则用act_UserRefresh.Execute;的方式来调用,不要调用某个按钮的 btn_UserRefresh.Click。9.调整工程的dpr工程文件,让 DMApp单元先加载,dpr工程文件中除去DMApp单元和主窗体外,其它的窗体创建代码全部删除掉。也可以通过 Project->Options->Forms 来进行调整。10.如果有其它子窗体,如有子窗体A来完成用户编辑的功能,单元文件是 WinUserEdit,窗体类是 Tfrm_UserEdit。如果窗体是要 ShowModal 使用,则将系统生成的var frm_UserEdit: Tfrm_UserEdit; 删除。给Tfrm_UserEdit添加类方法
class function CreateWinUserEdit(User:TUser):Boolean;实现代码如下class function Tfrm_UserEdit.CreateWinUserEdit(User:TUser):Boolean;
var
form:Tfrm_UserEdit;
begin
Result:=False;
form:=Tfrm_UserEdit.Create(Application);
form.SetUserInfo(User);
form.ShowModal;
Result:=mrOK=form.ModalResult;
end;其它创建想创建 Tfrm_UserEdit 窗体时使用 Tfrm_UserEdit.CreateWinUserEdit(User);的方法,根据返回值做下一步的操作。11.如果子窗体是 Show的方式打开,并且不能重复打开,则将系统生成的var frm_UserEdit: Tfrm_UserEdit; 放到implementation 下面。给Tfrm_UserEdit添加类方法
class function CreateWinUserEdit(User:TUser):Boolean;实现代码如下implementation
var
frm_UserEdit: Tfrm_UserEdit; class function Tfrm_UserEdit.CreateWinUserEdit(User:TUser):Boolean;
begin
Result:=False;
if Not Assigned(frm_UserEdit) then
frm_UserEdit:=Tfrm_UserEdit.Create(Application);
frm_UserEdit.SetUserInfo(User);
form.Show;
end;procedure Tfrm_UserEdit.FormClose(Sender: TObject; var Action: TCloseAction);
begin
Action:=caFree;
frm_UserEdit:=nil;
end;12.关于数据库操作,将TADOConnection 放在DMApp单元中。如要返回用户列表,在DMApp单元中实现function DMApp.DBGetUserList(AList:TList):Integer;
begin
执行SQL,返回生成User放到 AList对象中,返回总的个数。end;如果想要使用数据库绑定,则在DMApp单元放置一个ADOQ_User:TADOQuery;实现function DMApp.DBGetUserList:TADOQuery;
begin
执行SQL,返回数据集。
end;使用的原则是:将和界面无关的功能放在 DMApp单元中,这样可以整个程序都共享,实现一些方法来封装数据库的操作,不要在
窗体单元中写的到处都是SQL语句。13.要想程序不出错,那就不要将所有的代码分在一起,就象工厂不能所有人都在一个房间里干活一样,分层次,分类,代码结构清晰了
就不容易出错。设计就是从不同角度分类,分组,最后得到一个最好的组织方式。不要因为窗体少,就感觉能随便写,一个良好的习惯和套路让你不会过多的时间纠缠于解决一些基本的错误。结构清晰的你才能想得明白。
开发过程中最常见的业务如对一个数据表内容的增,删,改,将数据放在一个ListView中。很多人都会直接将ADO控件直接放在主窗体,然后在按钮事件里就开始查询表,得到数据级后,直接在数据集的循环里就开始向表格添加了,按钮事件里代码老长。
比如,100个用户,但是不能列出100行
因为
A用户只能看到其中的40行,但是只能编辑其中的30行(本人或下属录入编辑的),每行的m列可以显示,其中只有n1列可以编辑。本人录入编辑的可以维护的列数 与 下属录入编辑的可以维护的列数还不一样。
业务逻辑可以千奇百怪。
有可能并不是一个界面中去显示数据,在有的界面可能是显示+编辑,有的窗体只是显示。
所以将业务对象到列表的展示独立出来,要是写到 TAction 中,另一个界面中又得写一遍。
开发过程中最常见的业务如对一个数据表内容的增,删,改,将数据放在一个ListView中。很多人都会直接将ADO控件直接放在主窗体,然后在按钮事件里就开始查询表,得到数据级后,直接在数据集的循环里就开始向表格添加了,按钮事件里代码老长。
这样说的话就好理解了,不过这种情况我都是写在Common单元里面
数学的方法:归纳 猜想 验证 总结
工业的方法:计划 实施 检查 总结处理 (PDCA循环)编程的方法,更多地采用问题分解的方式,其处理流程也没走出类似的PDCA循环。
一、规划:
1)分析 分析问题,将问题分解为不同的子问题,衍生出各种类,构筑问题域的层次及其类体系。
2)模拟运行 依据类体系,模拟各种问题是如何分布在各个类中的,各个类是如何分工合作,从而解决各种各样的现实问题。
3)抽象接口 通过虚拟模拟运行,规划各个类之间的接口,定义好各个类的内在职责。
4)工作规划 将各种类及其要实现的目标及初步接口,分发到具体的开发人员中,编写长远工作计划及阶段工作计划。
二、按阶段工作计划落实编码 将各种类接口用具体的编程语言实现。
三、按工作规划检查与测试编码质量。
四、每阶段总结,并且进行对象抽取共享,同时不断完善与充实共享的函数库与类库。对优秀的对象给予推广。将好的经验写出来(解决各种问题的好的方法或方式,也就是模式抽取),在团队中共享。其中,构筑解决问题的类体系,实际上就是问题建模。这些过程实际上是存在于我们每一次编程之中,我们经常忽略最重要的问题规划阶段,而直接编程测试,将最后的总结抽取摆在重要位置,即在工作中总结经验再用于工作中,不是说这样不好,而是仅仅这样还不够好,习惯于缺少问题分析规划这一步,不利于长远发展,只能小打小闹。
所以提出一些基本的规则,只要遵守就有了基础的界面,业务,数据分离的架构了。
log4j:ERROR Attempted to append to closed appender named [A2].这样的错误信息。经过google发现可能是由于共用appender所致,具体原因还没有找到。 刚开始做项目,关于日志管理的理解还很初步,欢迎指教。
==============================================================关于log4j:ERROR Attempted to append to closed appender named [A1]. 之前的配置文件没问题,增加了一个logger之后无论怎么改,都会出现这个问题。最后无奈,将配置文件完全复原,竟然还是有这个错误。这是个web项目,突然想到将tomcat中webapp文件夹下部署的文件夹完全删除再重新部署,问题竟然解决了!然后重新配置多个logger,都没有问题。 不禁想到一句名言:对于此类不能用常理解决的问题,我们统统归结为人品! 粘贴我的log4j.properties如下: #定义2个输出端
log4j.rootCategory=INFO,A1,A2
log4j.logger.edu.tju=DEBUG #这一句为新添加的,将我自己的类的日志级别调整为DEBUG级别,顺便秀一下母校天津大学^_^
#定义A1输出到控制器
log4j.appender.A1=org.apache.log4j.ConsoleAppender
#定义A1的布局模式为PaternLayout
log4j.appender.A1.layout=org.apache.log4j.PatternLayout
# 定义A1的输出格式
log4j.appender.A1.layout.ConversionPattern=%-d{yyyy-MM-dd HH:mm:ss} %-5p [%c] (%t) %m%n
#定义A2输出到文件
log4j.appender.A2=org.apache.log4j.RollingFileAppender
#定义A2输出到哪个文件
log4j.appender.A2.File=./hrms12319.log
#定义A2输出文件的最大长度
log4j.appender.A2.MaxFileSize = 10000KB
#定义A2的备份文件数
log4j.appender.A2.MaxBackupIndex = 3
#定义A2的布局模式为PatternLayout
log4j.appender.A2.layout=org.apache.log4j.PatternLayout
#定义A2的输出模式
log4j.appender.A2.layout.ConversionPattern=%-d{yyyy-MM-dd HH:mm:ss} %-5p [%c] (%t) %m%n