中国开发网: 论坛: 程序员情感CBD: 贴子 391135
mhappy
共享共享,以前搜集的一篇资料,今天看看还是不错。。。关于MIS开发的
Delphi MIS开发架构心得
日期:2005年12月14日 作者:tonywam
广东,东莞,昨夜闷热.睡不着.想想琢磨软件开发也很久了.都是业余,没做成什么.可是看了不少东西.看了一些商品化软件的结构.为免新入门的朋友多走弯路,现本人一些体会说出来大家共同学习.许久没用delphil了,里面有些说法可能不准确

一 关于开发工具.数据库比较流行的是Delphi + Sql server.Delphi的好处我就不多说了.大家可以在网上找到很多.至于选择Sql server的原因,一是对中小型企业来说,Sql server的性能也还可以,价格相对于oracle 来说要便宜很多.再就是Microsoft的东西在易用性方面的确下了不少功夫.帮助资料齐全,本地化的语言也做得好.再加上目前国内的版权意识不是很高.所以选择Sql server的人很多.其实开源的firebirdsql , postgresql等等也还是很不错的,又不用花钱,但在国内用的人很少.

二 关于数据库连接层.用Borland 的BDE还是MS的ADO,到底哪个好.(新的dbexpress俺没用过,不敢发言).其实BDE和Ado都很优秀.BDE因为不是windows的东西,要另外安装,比较麻烦些.Ado则是高版本windows内置的.目前来看,用ADO的人数远远大于用BDE的.但BDE有一个好处,它的更新可控制性要比ADO强.它有一个UpdateSql组件,可以自定义更新的三种sql语句.这个优点已经被ADO.Net吸收了.

三 关于三层还是两层的问题.看了一下国内和台湾的几家较有名气的软件公司.三层是大势所趋.但目前做两层的还是多数.国内神xxx的Erp软件,台湾统x的软件用的是三层,同样用的是delphi的开发工具.东莞有家小软件公司做的进销存也是三层.都用的borland的midas技术.
国内的速x Erp是个假三层的,怎么说呢.它有个后台”应用程序服务器”在运行,但只起到客户端的连接监控作用,商业逻辑仍然是放在数据库后台的.所以说是假三层.

四 关于面向对象与关系数据库的矛盾问题.网上讨论很多.牵涉到三层的设计问题.牵涉到对象感知组件的问题.国外也有很多讨论.解决的方式大致有两种,一种是不用或者少用数据感知控件,自己写代码控制数据的变化控制与输入输出.这样可以封装实体类.以实体类或者实体类集合来工作,另外创建功能类,在功能类中写方法操纵实体类.不过这样一来工作量很大的.需要有 object/relational自动映射工具帮助实现.第二种是用数据感知控件.并且以dataset为中心.需要自己创建的实体类很少.商业逻辑还是要写sql语句,不管是放在什么地方.就是存储过程也不过是预编译的sql语句集合.这种方式比较大众化,对部分程序员的要求可以放低些(不要误会说这种方式的水平低).而且可以配合midas技术使用.国内神州数码的erp就是用这样做的.

五. 关于midas技术中的商业逻辑怎样安排的问题.台湾李维的书也将midas,也讲商业逻辑.但他好像没有怎样用midas实现商业逻辑(也许李维讲了是本人没有看到.).其实这个商业逻辑很简单,就在那个DataSetProvider的beforeapplyupdates 和afterapplyupdates中自己写好了.在这里要检查哪些值改变了,改变量是多少,针对这些改变量,我还要改变数据库中其他那些表的哪些记录的哪些字段值.举个例子.以开一张销售出货单来看.该张销售单卖了A产品100个,B产品50个,那么要在库存现存量中减去A产品100个,B产品50个,在财务的应收帐里加上这个客户本张单的欠款.具体要看你的数据库设计和数据流程.通常的erp软件里面商业逻辑很复杂,往往要改另外5,6个表以上,包括增,删,改都有可能.通常在数据库中写好store produce ,然后在中间层调用.这种情况基本上不用写触发器(trigger).对应触发功能是由应用服务器完成的.但如果没有用midas,是两层结构.往往免不了写trigger.是否另外写store product看情况需要.一般不推荐在客户端写商业逻辑,一方面编程难度加大,这种方式对用户的数据操作必须及时跟踪.另外修改了商业逻辑必须重新编译代码.不像在数据库端改了触发器即时生效,而且通常客户端较多,而数据库服务器只有一个,不存在版本更新的分发问题.

六 关于主从表,英文通常叫master/detail.做数据库通常免不了要用主从表.BDE和ADO都支持主从表.Ado.net就更方便了.此处不谈.不过要注意主从表的增加一定要放在同一个事务下主从表的构成有两种方式.一种是query组件,设置deltaildatast的datasource属性,然后在detail表的sql语句中用where语句关联主表.如 select * from detailtable where detailtable.masterid=: id,id为主表主键.另外是用adodataset,从表select语句如常,但设置其datasource为对应主表的datasource,,并设其masterfields属性为主表的主键.
注意在保存数据前主表beforepost事件中要开启事务,取消主从关系,在afterpost事件中保存从表数据,提交事务,恢复主从关系.具体原因我还不清楚.

七 关于dataset中的lookupfield的问题.一般好的数据库设计要符合范式.就是尽量减少数据库的冗余.想深入研究得学<数据库原理>.举个例子.一个销售订单.单据上有客户编号,客户名称,客户地址.交易金额等等.上面列出字段都是要显示和打印出来的.但实际上我们在关系数据库的订单主表中跟客户相关的就只保留一个客户编号字段.其他字段如客户名称,客户地址都不要在订单表中保留.但是前面说了我要显示啊,怎么办.有两种方法.一种是在某出地方另外放一个读取客户表的dataset,然后在订单主表saleordermaster中加几个类型为fklookup的查找字段,设好他们的属性指向customerdataset相关字段.这种方法比较常用.还有一种方法是数据库的设计不变,但在saleordermaster这个dataset中使用连接语句 比如
select 订单主表.*,客户表.* from 订单主表 订 inner join 客户表 客
on 订.客户id = 客.客户id.
可以一次join几个表,并不限于两个.对于这种join后的表,修改后保存有些特殊规定.一般只能修改其中一个物理表.此处我们修改的是订单主表.对客户的修改,属于基本数据,可以放在另外的地方.但怎样让程序知道我们要修改的是订单主表而不是客户表了.对BDE和ADO.处理方法不同.bde中可以设置saleordermaster这个dataset的updateobject组件(是updateSQL类型),在其中自己写更新语句,只更新订单主表即可,客户表忽略.对于Ado,一般因为相对于客户表,订单主表是从表,客户表是主表,ado有一定的只能,它会修改从表而保持主表不动.如果有问题,则可以明确指出只修改订单主表.用以下语句:
saleordermaster.recordset.properties[‘uniquetable’]=’订单主表’ 指明即可.
另外这种方式还有一点要注意.如果新增一条记录,客户表的客户id是可以填,但客户名称和客户地址它不会自动去后台数据库自行查找再填充的,你必须在dataset的afternew事件中自己想办法把他们填到当前记录的相应字段中.可以自己定义一些函数专为此用.比如getcusterombyId()等等.

八.关于sql server数据库的identity问题.我自己也曾困惑了很久.单纯对于数据库来说.有个identity字段是比较方便的.但是结合起前端开发工具来说.用不用,怎样用,就要仔细斟酌了.我见过几个软件,台湾统xERP,大陆速xERP,都是用的sql server .都不用identity字段.他们还是用整数做Primary key,但不是identity.这种安排的一个重要原因是主从表的同步问题.因为identity的值做主键必须等存盘成功后才知道到底是多少.而从表保存时就需要知道主表的primary key.我在第六部分说的”断开主从关系”可能也与此相关.在微软的体系中,他使用identity字段做主键.但他用的是嵌套的存储过程来完成的.如果纯面向对象开发来说,这个思路是好的,但对于我们borland族以dataset为中心的开发者来说.就不好用了.微软例子可以见Duwamish.网上书店..我个人觉得基本表的主键可以用identity,主从表的主表是不能用的,从表其实也是可以用identity做主键的.
(出处:http://www.delphibbs.com/keylife/iblog_show.asp?xid=18380)

相关信息:


欢迎光临本社区,您还没有登录,不能发贴子。请在 这里登录