程序员的自我救赎---1.2:代码生成器的使用
《代码生成器的使用》
今天中午阿杰聊了会,阿杰说看了我写的博客后。发现一个问题,把Winner框架整理成文档,要把Winner框架的核心思想
给写出来,比如为什么要选择Winner框架,市面上用于开发框架很多,比如以前我们刚工作的时候用的“动软代码生成器”,又或者
后来的EF,T4 等等。
其实,我的工作生涯中用过的代码生成器和框架只有2个,从技术上的层次来说没办法达到阿杰他们那样的高度,这也导致了我
没办法将Winner框架与其它框架的优缺点一一进行对比。当然,每个框架自然有他的好处,这个是毋庸置疑的。用我老师以前的口头禅
说就是:“存在即合理!”
我想了想,还是根据我的理解来写。不一定能写出Winner的精髓,后期只能像阿杰他们请教了。就代码生成器而言我就重点对比一下
“动软代码生成器” 和 "Winner 代码生成器"。
其实,我个人的观点动软的代码生成器界面是比我们的Winner代码生成器 要美观一点,但是代码生成器的职责是生成代码,而生成代码的关键因素是“模板”。
待会我再详细讲模板。
这里先说一下数据库,由于本身 Sqlserver 和 .Net 一脉相承,所以微软本身会更推荐使用Sqlserver数据库,sqlserver本身也易于操作,一直以来江湖传言
在大型项目开发一定要用“Oracle”,Oracle性能比sqlserver 如何如何好,这里其实我没有做过详细的测试。姑且听之信之,Sqlserver方面我们没有深入了解过,
使用Oracle的时候,对集群,备份 ,性能分析 等等方面 Oralce确实有很多优先的方案,比如“RAC”,“DataGuard”,“Rman” 等等(我们选择Oracle也是因为当遇到问题时网上能找到详细的解决方案)。
事实我们也看过很多案例比如做支付领域,物流领域。数据较大的行业基本都是Oralce为主,当然也有组合数据库使用(包括NO-sql)。
所以,Winner一直以来首选 的数据库是Oracle,当然也不局限于Oracle。这里特意说一下数据库方面,回到主题上来。“动软” 一开始我估计就是为sqlserver设计的
所以在代码生成上有一项功能我非常喜欢,动软可以根据实例 一键生成 整个项目。这点Winner则做不了,主要是因为Oracle一安装就只有一个实例,下面再是分用户分空间的。
我们没有把Oracle玩的那样的娴熟,前面的篇章中我也有讲到,因为我们的思想上一直认为“数据库”的职责是做数据库持久化存储,所以我们所有的项目表都是
建在一个Oracle用户下,技术员我们会单独分配“账户”,这里的“账户”不是指的Oralce用户。 再对“账户”进行表操作权限分配。
按下F5键,代码生成窗口,检索并选择要生成的数据表,添加 生成,搞定。
在上一篇《Winner2.0框架解决方案命分层规范》 中有特别讲到过数据库的命名规范,也体现了命名规范的重要性,在检索项目的时候,我们只要输入T项目项目 即可检索出该
项目所有的数据表, 在整个数据库中,这也规避了如A项目有个地址表,B项目也有个地址表,且两个地址表不能共用。这时就可以通过前缀来区分开来。
Sqlserver | Oracle | Mysql | Sqlite | |
动软代码生成器 | 支持 | 支持 | 支持 | 支持 |
Winner代码生成器 | 支持 | 支持 | 支持 | 支持 |
在数据库的支持上来说两者差不多,两者没有什么优势可言。Winner一直以来都是团队内部使用的代码生成器,这次其实也想通过公开它来让更多人提出意见使它更完善。
========================================华丽的分割线=================================
接下来说说重点: 模板
先从解决方案说起,动软遵循MVC原则,常规项目分为以下四层:
1,Dal 数据访问层
2,Model 实体层
3,Bll 业务层
4,项目显示层 (View)
其中 Dal,Model,Bll 都由代码生成器生成三份文件,复杂业务逻辑放置BLL业务层处理。
Winner,当然也是遵循MVC原则 同样遵循MVC原则,常规项目也是分为四层
1,Access 数据访问层
2,Entities 实体层。
3,Facade 业务层
4,项目显示层 (View)
其中只有Access 数据访问层由代码生成器生成。 (关于结构可以先浏览《Winner2.0框架解决方案命分层规范》)
这里有以下几点我们在项目开发中与动软有很大的区别。
A: 动软的框架中“工具层” 这一概念,如果需要使用到一些工具的话,需要自己建一个“Common”工具层,当然这个有很多前辈高人,都有
一套自己的“工具类”,只需要引用一个程序集就好。在这一点上,Winner框架中当然有专门的工具类Winner.Framework.Utils ,有其他要写
工具类需求的时候,Winner框架可以再Entities层中添加。当然,这点只是个“区别”,没有上面优劣可言。
B:动软架构中,生成三份文件本意是让职责更清晰,这点与Winner架构的概念不一样,Winner框架意在简历一个表对象,更贴合“面向对象”思想。
将“数据表”看做是一个对象,这个对象有基本的行为“增删查改”,这个对象有基本的特征“字段对应属性”。 对象的概念更清晰,相对动软的一层层
去调用,和 Winner的操作表对象,我的理解就是一个是“面向过程编程”,一个是“面向对象编程”。当然也有可能是我没用好动软,又或者是指用了
动软最基本的架构。 这里要说一下,EF也基于“表对象”概念 对表进行操作。
C:Winner有效的区分开了哪些是有代码生成器生成的代码,哪些是由程序员自己扩展的代码,如下图:
这样的好处是,当我数据库表字段更新的时候,我只需要代码生成器生成一份新的代码并复制--粘贴到GenerateCode文件夹即可,
默认的动软框架DAL中可能添加了很多自己根据业务扩展的方法,这个时候,要不就从代码生成器预览中一个方法一个方法的复制过来
要不就只能把自己写的代码复制到txt,然后更新DAL类后再复制回去。
《Winner2.0框架解决方案命分层规范》 中有带着讲到一点,Winner框架中“部分类的应用”,这里再贴图详细说明一下。
上图为代码生成器生成的Tnet_lock 表的DA类,下图为根据业务扩展的 Tnet_lock类
其实,DA生成的类对象,是一个类文件中,写了两个类一个是单条数据操作,一个是集合数据操作。更准确的说是 一个DA对象 是由四个分部类组成
生成的单条数据DA部分类, 扩展的单条数据DA部分类;
成生的集合数据DA部分类, 扩展的集合数据DA部分类;
其他的DA中只返回成功或失败,取值直接从DA的属性去取:
D,动软基本是教科书式的范例, View》 BLL》DAL 。(“》”代表调用)View不直接调用DAL,所以动软架构中BLL一些方法只是包装了一层DAL,
这里其实是多余代码。Winner,表操作中我们直接实例化Access对象,再填充表字段对应的Access属性,最后调用如Update(),Insert() 方法即可。
拿上面的修改银行卡信息举例,动软框架的操作相比之下就要复杂的多:
View中调用BLL-----》BLL调用DAL----》BLL实例化Model------》BLL将查询结果填充Model----》修改Model-----》调用DAL中Update()传入model;
动软的则要复杂的很多。
E:说一个动软的优点,动软代码生成器有一个功能我也非常喜欢,动软生成器有数据库字典生成的功能,这个winner代码生成器没有,当然可以做
只是作为一个公司内部使用的工具,我们一直没有去做。说白了,也是我们公司毕竟还是小公司方方面面施展不开,没有把架构小组给立起来。
=======================华丽的分割线=========================
最后贴一下,动软生成器 和 Winner生成器的模板,有兴趣的可自行下载动软生成器详细查看,至于Winner代码生成器,我今天建了一个Winner2.0框架群
可以加我们的QQ群即可。
代码生成器的原理都是写好模板,然后再根据模板进行关键字替换,如果有兴趣自己写代码生成器的可以自行百度,这里我不推荐自己写
代码生成器,推荐使用“CodeSmith”,基于CodeSmith的语法(关键字) 自己定义模板即可,这样可以省去很多对数据库操作的功能代码编写。
关于代码生成器的部分就写到这里,最后再补充一下:代码生成器只是节约重复性工作时间的一种工具,关键的还是思想。整个Winner代码生成器
最重要的思想是“对象化”。无论是用EF,还是动软,面对对象的思想能明确,代码就能写的灵活。 而代码生成器本身也是一种“封装”思想。将能公用、共用的
操作封装起来,方便程序员调用,而这个调用不是指程序中的调用,是指开发项目的“调用”。