大家好!
我平时用DELPHI编ERP程序,出于安全和效率的原因,最近几个月在学J2EE,也许是DELPHI用惯了,总觉得JAVA好是好,就是开发过程太繁琐了,不符合“开发以人为本的"理念。下面是根据我的需求草构的一个理想中的ERP开发框架,大家能否就这个框架提提意见,看看是否可行?
因本人编程水平有限,只能说个大概,但相信应该有很多高手能领会我说的意思吧:
1.此框架由三要素组成:组件、SQL、用于服务器端的一种面向对象的语言(可以为JAVA、C#、C++、OBJPascal或一种中间语言)。
2.它的核心是组件,类似于DELPHI中的Tform,Tedit,Tlabel,Timage,Tdbgrid组件等,一个组件由运行于客户端的表示层和服务器上的主体层构成,表示层可由不同的语言写成,分别运行于WEB,WINDOWS,LINUX,手机等平台,表示层与主体层之间通过加密式HTTP协议耦合,是不可分割的,组件具有自校验功能,客户端不可能篡改组件的表示层。例如同样一个Tdbgrid组件,在windows窗口环境下表现为一个带汇总、排序、导出、打印功能的表格控件,而在Web环境下就变成了一个具有类似功能但表现为自动分页显示的WEB表单,而在手机环境中仅表现为带滚动条的文本列表。
3.程序主体在服务器端运行,服务器容器实现对象池、连接池、线程管理、SQL优化(若有可能自动编为对应本地数据库的存储过程), 客户端运行的只是组件的表示层,用于客户的信息输入及输出,客户端相当于服务器端的一个映象,例如,服务器端生成一个窗口对象,客户端就会弹出一个窗口,服务器端的窗口对象上再动态生成一个按钮对象,客户端的窗口上也就会出现一个按钮。
4.程序员只针对组件编程,放弃对表示层细节的维护,可以实现让不懂编程的美工和程序员真正分开。例如:程序中有一个主窗口,一百个已确定的弹出窗口,以及若干个不确定窗口(窗口类型及其子组件在运行期动态生成,不能在IDE中用拖放的形式确定),这种情况下,可由美工针对每个确定的窗体,由工具软件来进行美化,产生若干个类似于CSS的格式文件,如:
Form1
windows窗口环境下:形状=圆角方形(宽=600;高=400);窗口底色=灰;标题栏=蓝色
Linux窗口环境下:形状=正方形(宽=默认;高=默认);窗口底色=灰;标题栏=红色
浏览器中:形状=圆形;标题栏=无;花边=花边1.jpg;弹出声效=吓一跳.wav;效果=淡进淡出
手机中:形状=带上下滚动条的容器
Menu1
windows窗口环境下:底色=深灰;图标们=ICO1.ico,ico2.ico...;
Linux窗口环境下:取默认值
浏览器中:风格=自定义菜单1.风格
手机中:形状=滚动的菜单项
Button1
windows窗口环境下:形状=标准按钮(top=10;left=10;宽=100;高=50);底色=灰;图标=按钮图标1.bmp
Linux窗口环境下:形状=椭圆风格(top=默认;left=默认;宽=默认;高=默认);底色=灰;图标=无;
浏览器中:形状=动画按钮风格1,位置=默认
手机中:形状=文字菜单
.....下略.....
至于动态生成的窗口、菜单等组件,解决方案有两种:1是由程序员来维护 2是取默认CSS风格
5.直接用SQL操作数据库,不做O-R映射(对于小企业编程人员来说,学会SQL已经很不错了,再学什么O-R就有点强人所难了,他们要的是学得快而又功能强的速成方法),
为了提高写SQL语句速度,我推存一种方法:先在EXCEL等电子表格中写好数据库的结构,有以下好处:
1).EXCEL表便于今后写文档,(实际上数据结构表你总是要写的);
2).可用工具(我自己已编好)直接根据EXCEL表创建空数据库并加上各种键和约束.而且可看性可维护性比直接写create table Child(Id int not null auto_increment primary key,Name varchar(100))之类的语句好多了。
3).编程时将EXCEL片段贴到程序中就写好了insert、update语句,加快编程速度(见下面示例),
4).省去了写字段的中文注释
5).可利用EXCEL生成SQL查询语句,不用在键盘输一个字母,就能将数据库的内容显示在DBGRID中并加上中文字段名。(具本方法因篇幅有限这里略过)
最好将来在IDE中可以直接支持嵌入"EXCEL表"格式,为什么这么说呢?你将下面从pu_insert开始到cd_tmp.first之间的行粘到EXCEL中就明白了:它在EXCEL中对齐了,因为它原本就是直接从EXCEL中粘过来的。
以下是用DELPHI语言编的一个发货过程示例:
string1:=cd_order.XMLData; //保存服务器端订单主表的数据
public_begintrans_repeatable; //调用SQL开始事务,控制事务等级为repeatable
try
view_reflash; //刷新订单主表服务器端视图
if (cd_order.XMLData<>string1) then raise ematherror.create('操作失败:当前订单内容已被其它人更改,请检查订单');
if pu_getonestring('select fhdcode from fhd where fid='+factid+' and fhdcode='#39+cxbuttonedit1.text+#39)
<>'' then raise EMathError.Create('错误:同号的发货单已存在!');
pu_insert('fhd',[ //写发货单到数据库中
' Fid integer 工厂代号 '+ factid
' FHDCode Varchar 20 单据编号 '+ cxbuttonedit1.text
' OrderNo Varchar 20 必填 定单编号 '+ cxtextedit3.text
' FHDDate datetime 必填 发货日期 '+ pu_today
' Remark Varchar 200 备注 '+ cxtextedit6.text
' car Varchar 10 车队代号 '+ cxtextedit1.text
' receiverman Varchar 10 收货人 '+ cxtextedit5.text
' DeliverTo Varchar 80 交货地点 '+ cxtextedit2.text
]);
cd_tmp.First;
while not(cd_tmp.Eof) do //待发货的机型存在cd_tmp中
begin
pu_exec('update stkcrd set qty=qty-'+cd_tmp.fieldbyname('发货数量').asstring
+' where fid='+_factid+' and modle='#39+cd_tmp.fieldbyname('成品型号').asstring+#39); //更改当前库存
cd_tmp.next;
end;
(...下略...)
pu_commit;
view_reflash_both; //同时刷新服务器端和客户端的视图
tell('发货成功,发货单号为:"'+cxbuttonedit1.Text+'"');
if iftell('是否现在打印发货单?') then sale_printfhd(cxbuttonedit1.Text);
cxbuttonedit1.clear;
except
on E:EMathError do begin pu_rollback;tell(E.Message) end
else begin pu_rollback;tell('程序出现未知错误,请与系统管理员联系') end;
if debug then raise;
end
//说明:pu_insert(...)在实际编译后是按"insert fhd (fid,FHDCODE...) values(1,'XXXXXX',...)"的标准SQL语句来运行的,也就是说,中间的” VarChar 10 收货人”相当于注释,增加了程序的可读性。
6.不区分MVC层次,简化开发过程。从上面的代码中,大家可以看到,以上代码是典型C/S模式下MVC不分的代码。但MVC不分也有它好的一面:代码简洁。MVC提出的初衷是什么?初衷之一是怕企业逻辑写在V层被人篡改, 本架构中因为V层只是组件的一个组成部分,而主体运行在服务器上,不可能被篡改,所以直接针对V层(组件层)编层不再是缺点反而是它的优点,它省去了C层和V层两个开发层的人员之间的沟通,MVC初衷之二是表示层与逻辑层混在一起不利于维护,但本架构中因为一次编写,到处运行,完全放弃了组件表示层(交给美工了),天生就不存在程序员要写HTML,美工要写JAVA脚本的问题,所以维护起来非常方便。再说对于小企业来说,一般也不存在企业逻辑要重用的问题,如果非要重用的话,将企业逻辑写在一个公用过程中调用就行了。
7.除非有打印、导出的客户端需求,它的数据处理都在服务器端。例如一个订单表有一万个记录,客户端每翻一次屏,服务器端就从数据库中取20个记录同时显示在DBGRID组件的服务器端和客户端,响应速度很快。有点象Delphi的MIDAS技术,但从技术上来讲比MIDAS更容易理解。
8.安全性:完全建立在组件上,每个组件设计必须确保没有安全漏洞,宁缺勿滥。
9.运行效率:不亚于J2EE或.NET,直接利用J2EE或.NET实现服务器端容器也可,若追求效率稳定要求不高的情况下,服务器端可实现原生码组件容器。
10.有一个集成式IDE,支持组件拖放,支持IDE内编译调试发布,无需ANT支持。
11.安装方便,一次安装就确保成功,不需要手工设什么环境变量。
12.该框架与其它相似技术的区别:
该框架与Tapestry区别:Tapestry只能开发WEB,只能使用java,而此架构可实现一次开发到处运行,支持各种语言。
该框架与.NET框架的区别:.NET必须针对WEB和窗口环境分别开发,且锁定在windows环境。
与Macromedia的Flex区别在于:Flex侧重于XML表示的表示层,将C层与V层分开了,且只能用于flash控件。
与微软的XAML的区别:XAML侧重于表示层,将C层与V层分开了,且只能用于longhorn平台。
与Mozilla中的XUL的区别:XUL侧重于表示层,将C层与V层分开了,且只能用于Mozilla浏览器。
与webwork的区别:webwork锁定在了java平台的WEB开发。
13.该框架缺点:1)程序中不能使用对平台依赖的API调用(对于ERP程序来说其实影响不大) 2)因为直接对数据库和界面操作,修改企业逻辑很方便了,想到什么,立即随手就能在代码里实现了,以致于我现在画的流程图(我到现在也没找到一个合适的建模方法)跟不上我修改编码的速度(我现在编的CS结构的ERP程序),整个程序象一堆面条搅在一起。不过有一点是肯定的,我编程和交流时一直用流程图,决不用什么UML图的,对于一个经常连自已需求都搞不清的小企业来说,没必要用对象包装,多此一取,事实上,RMDB中的每个表就是天然的对象了。
我不知道大家对这个框架是怎么看的,反正它就是我想要的理想中的适用于中小企业的ERP开发工具:学习周期短(无需学JSP,SERVLET,HTML,.NET,FLASH,ANT,struts,Hibernate等等,只要学会十几个组件的用法就可),开发速度快,安全性好,支持高并发访问量,一次编写到处运行(只要客户端能实现组件的表示层)。
题外话:我认为快速原型开发方法非常实用,它可以不要求程序员对企业专业知识学得很深,理想中的开发进度应该是这样的:开发的时间≈获取需求的时间。我不明白为什么两个小时就能讲明白的需求为什么会花一个月的时间去开发?如果客户在两个小时之内提出一个不明确的需求,哪我们就在两个小时之后给他一个粗糙的可运行的原型就行了。反正程序是改出来的,又不是盖房子盖好了就不能改了。客户觉得不好,他会告诉你怎么改的。如果客户在一个月内给你一个非常详细的需求,估计你至少也得花一个月才能编出程序来。程序是客户和程序员协作出来的。如果协作了几个月后,客户才明白他真正的需求是什么,而对程序员来说却是很难实现的(客户忽然有一天要求程序员在8秒内跑完100米),这种情况就很麻烦了,如果毁约有钱拿还好,没有钱拿的话,这几个月就算白干了,要避免这种情况,只有两种办法:一种办法是按合作期收钱(目前似乎没有哪个软件公司牛到这个地步),另一种办法就是在合作之前就培训客户,把我的最后这段念给他听,让他知道”程序是合作出来的”这个基本道理,告诉他合作期间提出非份需求对开发成本及进度将会是的致命,保证即使毁约也要对程序员作某种补偿。另一个问题是:如果客户确实没有错,他当时确实说是要8秒跑完100米的,只是程序员理解成了80秒跑完100米,怎么办?没什么好办法,沟通得再好,也不可能避免出错的,但是减小损失的途径是,如果开发速度非常快的话,本来要一个月干的活,三天就干完了,也就相当于少损失了27天的钱,这里就体现出开发速度的重要性来,总之我理解的框架的最终目标就是“加快开发速度”。
附框架示意图:
<img src="http://go.nvt.cn/zhangrex/kj.jpg">