当前位置: 首页 > 科技观察

使用通用框架进行三层架构开发

时间:2023-03-14 13:35:21 科技观察

三层架构是企业信息管理系统中流行的一种架构方式。众所周知,三层架构将信息系统分为数据访问层(DAL)、业务逻辑层(BLL)和界面表示层(UI)。三层架构的好处是系统按照代码在系统中的层级进行拆解,然后通过业务模型(Model)连接起来,减少了系统各个层级之间的差距。耦合度提高了程序开发和后期维护的便利性。由于三层架构是自上而下分层,而不是按照功能和应用领域,所以三层架构每一层的侧重点不同,数据访问层侧重于与数据库的关系。在处理部分,业务逻辑层侧重于业务逻辑处理部分,而界面表现层侧重于人机交互部分,所以三层架构也体现了系统开发的顺序和分工到一个层次。一定程度。本文将根据自己对三层架构的理解,使用General框架从零开始搭建一个信息管理系统的初步架构,以展示General框架在信息管理系统开发中的优势。由于不同的人对架构有不同的理解,本文不强调架构的正确性,只是提供一个三层架构的示例,目的是简化开发,方便编程。本文示例项目是一款小商品库存管理软件,源码请参考通用框架中的Sample.Market项目。第一步设计业务模型由于是示例项目,本文绕过需求分析过程,直接从业务模型设计入手。至于为什么要从业务模型入手,目前主要有两种开发顺序,即业务驱动设计和界面驱动设计。业务驱动设计强调业务是系统的核心,所有的编程工作都围绕着业务设计,而界面驱动设计则认为界面是客户、项目经理、设计师、程序员最好的沟通工具,所以一切都应该确定以界面为首要目标。而我认为这两种方式哪种更好,要看实际情况。如果项目不是很大,接口容易确定或者客户更注重接口设计,那么接口驱动设计当然是首选方案。您可以从界面开始。从它入手,做一个DEMO,等客户满意后再开发业务流程。相反,如果业务逻辑更重要,当然业务驱动设计是首选方案,而信息管理系统的开发大多是以业务为中心的,所以去掉需求分析后的第一步就是设计业务模型作为第一步。第一的。商业模型设计可以使用Excel、PowerDesinger等工具,先用Excel整理出商业模型比较的核心数据信息,然后用PowerDesinger制作商业模型图(即ER图),然后生成实物图数据库模型,然后生成数据库。本文的业务模型图设计如下,生成各种数据库对应的物理数据库模型,然后生成数据库的建库脚本。Acess需要一定的技能才能通过脚本创建数据库。这个方法可以百度一下。我通过PowerDesinger生成的建库脚本创建了Access、Sqlite、SqlServer2000、SqlServer2005、Oracle、MySql数据库,数据库名称为Market。#p#第二步,生成实体模型数据库创建好后,首先使用VisualStudio创建一个名为Sample.Market的解决方案,创建Sample.Market.Logic(业务逻辑层)、Sample.Market.Model(实体模型library),Sample.Market.WinForm(WinForm接口表示层),大家发现为什么没有创建数据访问层,因为我是用General框架开发的,General框架支持多数据库,有ORM功能,所以数据访问层出现是没有必要的,General.Data也可以理解为一个通用的数据访问层。但是,从系统解耦和更有针对性的多数据库支持出发,在系统内部再增加一个数据访问层也是有好处的,但是会带来更多的编码和更多的后期维护成本。利弊需要自己权衡。项目创建完成后,我们可以使用Generalcodegenerator这个强大的工具一次性快速生成实体模型。注意,实体模型是从数据库生成的,但实际上实体模型应该来自业务模型。因为数据库是从业务模型生成的,而实体模型是从数据库生成的,三者是完全一致的,其实从开发的角度来说更方便实用,因为只要了解其中一个,你可以理解三者。被完全理解。但问题是如果商业模式改变了怎么办。这个问题困扰了我很久,因为虽然有先进的工具支持,但是还是很难从业务模型生成物理数据模型,修改数据库结构,再从数据库生成实体类。很累的一件事情,到现在我也没有特别好的方法来解决这个问题,我什至想过做一个从设计业务模型到生成数据库再到生成实体类的完整的解决工具,但是工作量太大对我来说很难完成它。在这里我只能提出以下几点供大家参考:1)尽量减少商业模式的修改。前期的设计尽量做到完美,留下足够多的冗余字段,并将修改成本告知负责业务研究的同事。尽量让客户签字确认修改;2)数据库与测试数据分离,如通过SQL脚本输入测试数据,以免修改数据库结构,造成测试数据丢失;3)工具不是人,没有人的智慧。修改了类的某个部分,但是在重建库或者重新生成实体类后忘记恢复,这样很容易导致莫名其妙的BUG,所以尽量避免一下子重建库或者重新生成所有的实体类,但是小范围修改;4)如果改动太多,放弃业务模型,直接去数据库修改。这样会减少很大一部分工作量,避免过度劳累。通用代码生成器的使用可以参考压缩包中的教程。生成实体的模板已包含在模板库中。动手能力强的可以自行修改或制作符合自己习惯的模板。#p#第三步,创建界面表现层制作软件界面其实是一个很累的工作,占整个系统开发时间的一半左右,但是界面开发也有很多技巧,比如通过配置动态生成菜单、通过配置动态生成表格列、表格自动生成、自动收集填充、下拉框自动生成、搜索项自动生成和查询语句自动生成、渲染器自动绑定字典等这些技术可以大大提高开发效率,减少很多重复性工作。以后我会慢慢介绍这些技巧。本文将介绍一种自动收集和填写表格的技术。General.WinForm.FormHelper和General.Web.WebHelper都有一个方法叫CollectAndFill,分别对应表单和网页的收集和填充,可以用于Object、DataRow和控件集的任意两个。收集填写时间,比如表单控件收集值赋值给实体,实体收集值赋值给表单,但是前提是表单的控件需要命名与对应实体的属性相同。使用如下方法:创建实体并收集表单值:1Goodsgood=newGoods();2FormHelper.CollectAndFill(这个,好);查询实体并赋值给表单1Goodsgood=goodsLogic.GetGoodByCode(Number.Text);2FormHelper.CollectAndFill(好,这个);实际上控件的收集和填充是通过各种控件对应的工具类来完成的,所以如果有无法收集或填充的控件类型,可以通过添加注册新的工具类来实现。详情请参考源码。第四步是创建业务逻辑层。最重要的业务逻辑放在最后,因为业务模型和接口确定后,业务逻辑不能跑出圈外,只要按需求完成就行,可能有人会说是吧不是说先创建业务逻辑再创建接口。事实上,这种业务逻辑的方法很难确定,应该优先考虑接口的创建。通用代码生成器还可以生成业务逻辑层的代码,甚至可以完整生成接口层的代码。如果项目代码优化得好,先生成再修改可以节省很多时间,但大多数情况下这项工作的重复性不高,不需要自动生成来完成。创建好业务逻辑类后,使用DataManager进行数据库访问操作,比如下面的方法通过ID获取商品信息:///

///通过ID获取商品信息//////ProductID///publicGoodsGetGoodByID(intid){returnDataManager.Default.Find(id);}一行代码即可完成;入库方式://////商品入库//////商品信息///入库date///入库数量///publicReturnCodeStockInGoods(Goodsgood,DateTimestockDate,intamount){Transactiontran=DataManager.Default.BeginTransaction();try{//查询是否有编号已经存在的商品GoodstmpGood=DataManager.Default.FindFirst("Number=@bh",good.Number);if(tmpGood!=null){good.ID=tmpGood.ID;good.Attach();good.stock数量=tmpGood.stock数量;good.stock数量=tmpGood.stock数量;good.stock数量=tmpGood.stock数量;good.stock数量=tmpGood.stock数量;}else{good.Detach();}if(good.stockquantity==null)good.stockquantity=0;if(good.stockamount==null)good.stockamount=0;if(good.purchase==null)good.purchaseprice=0;if(good.purchasequantity==null)good.purchasequantity=0;if(good.stockamount==null)good.stockamount=0;//调整库存good.stockquantity+=amount;good.stockamount+=amount*good.purchaseprice;good.stockquantity+=amount;good.purchaseamount+=amount*good.purchaseprice;good.averagepurchase=good.purchaseamount/good.purchasequantity;DataManager.Default.Save(good);//保存入库记录GoodsIngoodsIn=newGoodsIn();goodsIn.Goo_ID=good.ID;goodsIn.date=stockDate;goodsIn.number=good.number;goodsIn.purchase=good.purchase;goodsIn.retailprice=good.retailprice;goodsIn.quantity=amount;goodsIn.amount=amount*goodsIn.purchaseprice;goodsIn.productiondate=good.productiondate;goodsIn.shelflife=good.保质期;goodsIn.expirationdate=good.expirationdate;goodsIn.productionbatchnumber=good.生产批号;goodsIn.supplier=good.supplier;DataManager.Default.Save(goodsIn);tran.Commit();returnReturnCode.Successed;}catch{tran.Rollback();throw;}}即使是对两个表来操作使用事务,代码还是很短的由于每个数据库的SQL都略有不同,所以要兼容多个数据库其实是非常困难的。General框架的数据库操作是通过拼接SQL语句完成的。没有像EntityFramework或NHibernate的HQL这样的Linq。自带查询语言,很难兼容多种数据库,而本示例程序可以兼容Access、Sqlite、SqlServer、Oracle、MySql数据库,主要有以下几点:1)通用框架对各种数据库对应的查询生成器,同一个方法对于不同的数据库有不同的SQL生成实现;2)通用框架具有替换不同参数前缀的能力。比如在Oracle中,参数前缀是“:”,而不是SqlServer中的“@”。通用框架“@”作为通用前缀将自动替换为Oracle的“:”以实现兼容性;3)本例中没有使用一些特殊的SQL语句,各个公司的数据库对常用的select、insert、update、delete语句的兼容较好。最后可以在General框架中打开示例程序查看具体的使用方法。它还包含一个性能测试程序来测试通用框架的性能。相关源码下载请参考上一篇文章。欢迎发表评论。