回顾我的软件开发经历:我与代码生成器的涅槃之路

前言

这是我《回顾我的开发经历》系列的第二篇,聚焦于我与代码生成器的故事。从最初的简单工具到最终演变成一个功能强大的ORM框架,这段经历不仅让我在技术上得到了极大的提升,也让我深刻理解了重构、设计模式和系统架构的重要性。希望通过这篇文章,能为大家提供一些启发和思考。


初识代码生成器

工作几年后,我第一次接触到了代码生成器。虽然最初的版本非常简单,但这个思路让我眼前一亮。在接下来的十几年里,我不断扩展和完善这个代码生成器,最终实现了通过数据库自动生成具备完整增删改查功能的网站。这段经历让我受益匪浅,我将其中一些关键点总结在这篇博客中:代码生成器的成长历程


代码生成器与阅读

刚开始编写代码生成器时,我对面向对象开发的理解还很模糊。当时,我正在阅读《C# Primer Plus》,一边学习,一边将书中的知识应用到代码生成器中。有时遇到问题不知道如何解决,有时学到新的知识点,立刻就能在代码生成器中实践。这段经历非常奇妙,我甚至常常在走路时思考书中的内容,以至于多次错过路口。我在《我的读书生涯》中回顾了这段经历。

在这种边学习边实践的过程中,代码生成器逐渐发生了变化:功能不断扩展,代码量减少,但继承关系变得复杂。我甚至为业务对象设计了一个基类,后来发现这是一个误区。尽管如此,代码生成器逐渐演变成了一个框架------一个属于我自己的框架。代码生成器本身的代码量和生成的代码都显著减少,功能却更强大,可维护性也更强。


ORM框架的诞生

有时候,改变源于一句不经意的话。在与同事讨论时,有人提到"不应该将SQL语句放在逻辑代码中"。这句话触动了我,我开始在代码生成器中将SQL语句从代码中移除,这为后来形成ORM框架奠定了基础。

ORM框架的另一个技术来源是C#的开源项目DNN(Dot Net Nuke)。我从中学到了CBO(基于元数据的对象创建与赋值),这成为ORM框架的核心技术之一。例如,将一个DataTable中的Row转换为对象,或将对象转换为DataRow;还有Null类。此外,DNN中的策略模式也为我提供了灵感,使ORM框架能够支持多种数据库。

在2006年到2007年间,我实现了一个类似MyBatis的ORM框架,甚至一度觉得它比MyBatis更好用(惭愧中)。


XML读取与数据库访问

在ORM框架中,我将SQL语句和参数放到XML中,并设计了一个访问框架,实现了缓存和更新功能。为了支持多种数据库,我应用了设计模式,尽管当时对设计模式的理解还不够深入。后来我意识到,设计模式并不是刻意学习的,而是在实践中自然"长"出来的。我多次重构数据库访问程序,最终形成了一个稳定且高效的库。


技术追求的弯路:Attributes

在这段经历中,我也曾走过弯路。例如,我曾过度使用C#的Attributes,甚至将其放到业务对象类中。后来意识到这是错误的,便将其移除。这段经历让我明白,技术工具的使用需要适度,不能为了炫技而牺牲代码的可维护性。


前端控件的发展

在代码生成器的早期,我主要做Web开发,前端使用ASP.NET,后来转向Castle Monorail。为了减少Web页面和后台的代码生成量,我不断扩展Web控件,将能前端处理的功能尽量放到前端,并抽象出通用功能。前端控件的抽象经历了两个阶段:

  1. 第一阶段 :抽象出包含后台代码的Web控件,例如扩展DataGrid和TextBox控件

  2. 第二阶段:使用纯前端控件,进一步提升灵活性和可维护性。


前端自动输入合法性验证框架

除了扩展控件,我还为前端输入合法性验证设计了一个框架。通过JavaScript遍历所有DOM控件,根据扩展属性(如是否为空、最大最小长度、是否整数等)进行合法性验证,并在控件下方弹出提示信息。这一设计大大减少了后端验证的负担。


使用模板技术

最初,代码生成器的所有代码都是通过字符串拼接生成的。随着框架的升级,生成的代码量减少,字符串拼接的工作量也大幅下降。后来,我意识到可以使用模板生成代码,于是设计了一个简单的模板引擎,用"#***#"格式替换变量。再后来,我引入了VTL等模板技术,进一步减少了代码生成器的代码量。


Excel操作

我为框架添加了Excel导入导出功能,根据数据库结构生成Excel文件,并支持数据合法性验证和格式设置。用户可以在Excel中编辑数据后,再导入系统,实现批量添加数据,同时严格遵循主外键关系,避免脏数据。这一功能在后来的视频监控配置中发挥了巨大作用,将原本需要数天的配置工作缩短到十几分钟。


框架与库

经过几年的开发,我发现框架不一定要以单一的形式存在,而是可以拆分为多个独立的库。每个库可以单独使用,组合起来又能形成一个完整的框架。基于这一思路,我将框架拆分为数据访问库、元数据映射库(CBO)、SQL缓存库、前端合法性检查库、前端控件库、Excel导入导出库和通用库等。


代码生成器的扩展

代码生成器最初是一个简单的Form页面,后来逐渐扩展为包含多个Panel的界面,支持数据库表树、代码生成区域、数据库表结构选择以及代码类型选项。生成的代码不仅支持ASP.NET,还支持Java、C++、Castle Monorail的页面代码以及多语言配置。


代码生成器与重构

重构的习惯是在编写代码生成器的过程中逐渐养成的。从最初的混乱代码到一个完整的框架,再到拆分为多个库,重构起到了关键作用。这段经历让我形成了几个重要的认知:

  1. 重构要小步快跑,步子太大会迷失方向。

  2. 代码越重构,越敢动它;否则,代码会逐渐僵化。

  3. 几次小的重构后,需要进行一次相对完整的验证,避免浪费时间。

  4. 重构的目标可以大一些,但要从小步开始,逐步实现。

  5. 重构的最终目标是让代码更清晰、更灵活。


后续

这个代码生成器我写了十几年,乐在其中,也学到了很多。我还用Python和Java实现了类似的工具,例如Python版的代码生成器(Mysql_CodeGen)和Java版的框架(HiJDB)。此外,我还开发了一个C#版的DataGridView辅助类(DataGridView辅助类)。


总结

通过编写代码生成器,我的技术能力得到了极大的提升,对重构、面向对象、设计模式、前端技术和后端技术都有了深入的理解。唯一的遗憾是,这段经历主要是单打独斗,如果能与更多人合作,可能会成长得更快,收获更多。在未来的工作中,我希望能再次找到类似的机会。就像我的代码生成器一样,从无到有,从框架到库,不断重构和突破,逐步完善自己。

其实,在开发方面,我也的确又遇到了类似的工作,例如:ACE,例如后来做的智慧校园平台。

就像我的代码生成器,从无框架到有框架到打破框架形成多个库,不破不立,期望在任何好的或坏的情形下,都有重构自己的勇气,正反正的螺旋上升,逐步完善。

相关推荐
在下小孙16 分钟前
C#——类型转换
开发语言·c#·变量类型转换
向宇it3 小时前
【从零开始入门unity游戏开发之——C#篇46】C#补充知识点——命名参数和可选参数
开发语言·unity·c#·编辑器·游戏引擎
深度混淆3 小时前
C#,入门教程(03)——Visual Studio 2022编写彩色Hello World与动画效果
开发语言·c#
小王子10246 小时前
面向对象分析与设计Python版 GOF设计模式
python·设计模式·gof·面向对象分析与设计
ellis19708 小时前
详解C#反射(Reflection)
unity·c#
code_shenbing8 小时前
C# 数据结构全面解析
c#
pchmi9 小时前
C# OpenCV机器视觉:常用滤波算法
人工智能·opencv·c#·机器视觉·中值滤波
abments10 小时前
C# OpenCvSharp Yolov8 Face Landmarks 人脸特征检测
开发语言·yolo·c#
智驾12 小时前
C++,设计模式,【目录篇】
c++·设计模式