两年多前,我把自己曾经为了快速开发各种web后台管理类系统,所额外创作的一套自动化生成CURD代码的程序进行了简要描述, 并记录在了CSDN上 ,还以此畅想了如何实现自动化编程,截止现在竟然也有了五千多阅读和小十条评论。
毕竟这是很多程序员关心的话题,自动化编程,多么激动人心而又让人感到恐惧的事情!
从写文章的角度,当时的那篇其实相当于一张草稿纸。现在我把当时的设计实现和思维成果重新整理。2020年了,希望它还能有价值。
由于那段时间总是基于ThinkPHP3.1.2和H+ 开发后台类型的系统,在没有这个工具前,感觉自己很多时候都在从已经开发完成的模块中复制文件到正在开发的新功能上,然后修改复制过来的文件名,还有文件中的类名 、数据库表名、主键名、字段名、模板标题、链接……
这些复制和修改工作没有任何的技术难度,有的只是枯燥和乏味,还有偶尔某些地方需要修改但被遗漏。我还发现很多功能除去对相关业务表的增删改查,几乎没有多少业务逻辑。有些功能需要编写一定量的业务逻辑,但也需要先完成基本的增删改查功能。
直到有一次,又一个后台类的系统需要我来开发,估时两个星期,初期数据表大约有三十来个。没错,很多业务表都需要有个对应的增删改查功能。
于是我大胆的开始了我的表演,我一边按照以往的方式在开发着那些乏味的功能,一边加班设计着这个辅助我开发的工具。一个星期之后,时间过去一半,这个系统的开发进度远没有达到一半,不过我一点儿也不担心,因为在周末已经用这个工具开发了几个功能,我可以预料接下来一个星期的时间我的效率将会大大的倍增。
这个工具的来源大概就是这样。
为了把这篇之前写过的文章再搬过来并且整理好,我特意从以往的代码堆里找出了 这个程序 。 现在我把它部署出来,又看到曾经熟悉的界面。
除了顶部的介绍说明和菜单,首先看到的就是两个深色背景的代码编辑框,依次分别是模型文件和控制器文件。控制器里有预先写好的增删改查等函数,当时很少用到模型层,几乎只是用来定义表名。
滚动条往下,还有三个白色的代码编辑框,里面分别是列表页、新建表单页、编辑表单页。
这五个代码编辑框里预加载的代码都是我事先写好的“模板”代码,自动生成CURD的关键之处,在于可以根据现有表的所有字段和类型,加上一些手动的设置,自动生成相关代码段并替换到“模板”代码中去。当工具根据要求生成功能的基础CURD代码后,可以继续在五个代码编辑框中去完善这个功能的业务逻辑。
接下来请跟着我的箭头,演示生成一个功能的CURD代码。
1、点击右上角文件菜单,选择“新建项目”
2、在弹出的“项目属性”窗口中配置数据库及模块
选择数据库是为了找到指定的数据表,设置模块英文名称和模型名称则是用来定义ThinkPHP的控制器和模型名。
下方的模块中文名和选择所属菜单,是为了自动生成创建RBAC节点的SQL,不选择所属菜单则会作为顶级菜单,见SQL中“/*设置菜单编号*/ SET @m=’0′;”。在那之前每给后台系统增加一个菜单都需要手动去RBAC相关表中添加……以前的泪就不多说了,继续看下图。
眼尖的你可能注意到了第二个表名为“autocode_project”,那正是我这个工具用来保存数据的表,是否还记得右上角“文件” 菜单下还有个“打开项目”和“保存项目”?
3、这里我选择的是“楼栋房间床位表”:building_room_bed,并设置好模块名称。“所属菜单”只对这段SQL中的变量“m”有影响,与后续无关
4、配置好后,点右下角的确认按钮,进入到配置字段的步骤,这个界面是自动生成代码的关键
默认会识别到这张表的主键,如果需要更换,可在“选择主键”下拉列表中选择(其实这个更换主键的操作有点多余)。主键字段名会作为变量替换到“模板”代码中去。
中间有两个“int”类型的字段:“building_id”和“room_id”,它们分别是“building”表和“building_room”表的主键,对比我当前所开发的功能表“building_room_bed”,可以很简单的通过表名判断它们之间的关系。即:bed_id是床位编号,room_id是床位的所属房间编号,building_id是房间所属楼栋的编号。
5、我判断了只有是“int”(“bigint”、“smallint”或“tinyint”)类型的字段,数据列表的下拉选择项中会有“数据列”和“联表”这两个选项
数据列表的设置会决定在数据的列表视图上如何显示该字段的值,为了便于理解,我先放个图出来
可以看到,在列表中,所属楼栋和所属房间这两列显示为数字是不恰当的,应该显示为相关联表的名称字段。假如以上building_id字段的数据列表设置为“联表”,会立即弹出以下窗口
设置好后点击确认
列表上的图我就不重复截了,总之原先显示成数字,这下会变成对应的名称。
假如有个status字段也是int(或tinyint)类型,那么应该把数据列表设置成“数据列”,选择后如下图。假如输入“启用,禁用”,则status为1时会在列表中显示为“启用”,status为2时显示为“禁用”
6、DOM形式用于设置该字段在新建表单、编辑表单以及列表页的顶部搜索栏中使用何种形式的输入元素,除了默认的“文本框”类型外,int类型的字段额外有“列表框”的选项(数据列表设置为“联表”或“数据列”后会自动变为“列表框”),字符类型的字段额外有“文本域”的选项(搜索栏仍为文本框)
7、数据标题取自该字段的注释信息,可以修改
8、列表位置用于排列该字段在列表页面中从左到右数的所在位置,0表示不在列表中显示该字段
9、搜索条件默认为“否”,即不作为列表上的搜索条件,所有选项如下
10、表单选项如下,用作新建和编辑时是否出现该字段的输入元素,以及如果出现是选填还是必填
以上“配置字段”窗口中各选项设置每变动一处都会立即生成代码并分别更新到五个代码编辑框中,关闭该窗口后还可以继续点击右上角“编辑”按钮重新打开“项目属性”窗口和“配置字段”窗口
11、当一切都设置得差不多了,甚至也通过代码编辑框写好了剩余的逻辑,可以点击“文件”菜单下的“保存项目”,如果项目目录中没有与当前五个代码文件重名的文件,会直接创建相应名称的文件夹和文件并提示保存成功,否则会把所有重名的文件列出并提示
这是我的字段设置,下面我把生成的五个代码文件分别贴出来
以上五段代码完全基于工具生成,没有进行额外修改。要特地说明的是,业务上需要增加一点点逻辑,比如把building_id和room_id这两个字段的输入元素(下拉 框)做成联动(这只需要极小的改动工作),新建床位时应该给create_time字段写入当前时间(“模板”代码中已经有,只需要去掉注释即可)。
为了便于对这个工具进行功能说明和使用介绍,我选择了“building_room_bed”这样的表结构。同样的,对building表、building_room表以及其他所有需要做增删改查的表,都可以极快的完成相关的编码工作,可以节约出来的丰富的时间,专心的面对业务逻辑。
在当时后续的各个项目中,有很多功能模块是由我和我的同事使用这个工具直接生成的代码,对效率的提升产生了明显的作用。虽然这个工具并没有被一直的完善下去,虽然我自己也两年多没再使用过它,但我希望我当时对这个工具的设计,能够影响人们对编程工作的看法,带给同行们一些灵感。
可能写增删改查写烦了的程序员们,多少会有一些类似的想法和沉淀。以上可以看出,这个工具的设计及其生成的代码称不上多好,最多只能算是对一些思路的简单实现,而我当时确实还有对这个工具进一步升级的想法,大致有两个要点:
1、通过设立团队规范,要求设计表结构时通过标准化的表注释和字段注释,提高“配置字段”步骤中的自动化能力;
2、当能够实现单表的全自动化生成代码时,增加自动识别数据库中所有需要生成CURD代码的业务表,从此只需要选择一次数据库,整个库中所有增删改查的功能瞬间完成,程序员只需要稍微修改部署代码,完全专注于业务逻辑开发。
按照新的想法设计过一小段时间,但最后没有继续去实现它。因为我逐渐远离了那种增删改查的工作。继续实现它需要时间,而对我来说,基于之前的成果做第二个版本已经不是那么有意义的事情了,不过我没有忘掉这个事情,我仍然打算把这个思路在UIM框架中再实现一次,并且不再基于H+,而是由开发者自行选择前端主题。
关于自动化生成CURD代码的过往和计划先讲到这里。因为有过这个历程,我再说说自己对全自动化编程的思考。
我不想把对自动化编程的概念往人工智能上面套,特别是现在人工智能这个词已经变得像神棍的口头禅一样。永远记住,程序不会拥有人类的意识!
我所认为的自动化编程,只是一个辅助工具,这个工具永远都是由人来操作。全自动编程只是对于这个工具的自动化程度的一种描述,应该是“尽可能少的需要人工操作配置”的意思。就像自动反导系统和人工操作雷达、人工发射拦截弹的区别,只是把一个个以往明显由人来操作的步骤变成了机械化,而如果真的一个人都没有了,自动反导系统也会变得不能自动。所以“全自动化编程”也不过是“半自动化编程”一点一点量变过来的而已。
说了这么多,好像还是没有探讨到全自动化编程的点上,到底全自动化编程该如何 实现呢?我的想法是把编程需求场景化。
假设先不去思考我们编程所要实现的具体软件是什么功能,而是把编程这个工作本身当成是一个需求,我们可以列出所有已知的编程工作的实施场景,比如:
1、使用PHP与HTML技术开发web类型的系统;
2、使用C#与Java技术开发安卓手机应用;
3、使用c与蓝牙技术开发智能硬件类型的程序;
以上我随便列举了三种编程场景,这三种都还比较笼统。前面提到的自动生成CURD代码就属于“使用PHP与HTML技术开发web类型的系统”这个场景,我们继续来对这个场景做更进一步的细分:
1、使用PHP和HTML开发web小游戏;
2、使用PHP和HTML开发web聊天工具;
3、使用PHP和HTML开发web管理后台;
这回更具体了一些,很明显以上“自动生成CURD代码”属于“使用PHP和HTML开发web管理后台”这个更细分的场景,那如果我们再把这个场景继续细分N次,可能会得到以下几个场景:
1、使用CI框架和layuiAdmin开发数据管理系统;
2、使用ThinkPHP框架和H+主题开发数据管理系统;
3、使用Yaf框架和easyui开发数据管理系统;
前面介绍过我当时正是基于ThinkPHP和H+实现的“自动生成CURD代码”这个工具,而自动完成增删改查的功能对于开发数据管理系统正好合适。我们先赶紧得出两个粗略的结论:
1、只要预先实现某个细分场景的自动化编程,当正好需要开发这个领域的程序时,先前造好的这台“机器”就可以派上用场,展现出机械化的高效了。
2、当实现自动化编程的的细分场景越来越多,就可以从理论上满足越来越多种类的应用程序的自动化编程。
但是细分到这一步,是不是意味着有太多太多的场景?
确实是,从宏观走向微观,场景太多太多,实现这么多场景的自动化编程根本就不现实。好在并不是每个场景都需要实现自动化,我们可以先找到使用频次较高的场景去实现,这样做的回报也是比较高的(正因之前编写增删改查的代码频次很高,我才去实现了以上的工具),除此之外,某些相似的场景也只需要实现一次(比如以上三种“ 开发数据管理系统 ”的场景),或者把它们进一步抽象成相同的场景。
很多人都知道智能建站程序,我们可以把智能建站也看成是一个细分的场景 ,它较多的应用在简单企业官网的建设上。
好了,我用了太多的篇幅来从宏观讲“细分编程场景”对于“自动化编程”的意义, 再反过来从微观到宏观的角度,如果把一个个已经实现自动化编程的细分场景进行融合,就可以把“自动化编程”从“理论上”更贴近实际。 因为真正的软件开发工作会包含对多种不同形态的需求点的实现。
讲完了“细分场景”与“场景融合”,再说说我对自动化编程如何完整实现的浅见。
之前我认为自己抓住了自动编程的重点:需求与数据结构。
现在仍然认为这两点非常的重要,但可能还有其他非常多的点。
我自己对这两个重点的定义:需求是软件价值的表达,数据结构是结合软件需求与软件构架后所产生的软件的“形状”。
还是偷点懒,直接把原来码过的字搬过来吧:
根据软件需求自动形成架构方案和数据结构并不是我现在的目标,它是自动编程的高级阶段,不过我相信我最终将实现它。
我认为自动编程的最终阶段是根据完整的需求(当需求不完整时协助你完善你的需求)自动创建方案,并为选用的方案自动编写代码,自动编译或部署,当然还是以场景为概念,当你需要在哪种场景下让它自动编程,那么你需要为它去建立它应对这个场景时的需求分析、方案构建、组件选用、代码编写等各种处理过程,只需要建立一次便可让它永远学会这种场景下的自动编程,你还可以为你构建的这个场景进行升级,那么它也随着你对这个场景的升级而提高应对这个场景自动编程时的“段位”。
我之前提到“自动化编程”的终极实现,是一定需要以开放的态度才能达成的伟大构想。倘若真的能够建立一个开放的平台,建立一套标准,让所有人都能够提交自己已经实现自动化编程的场景,那么这一定会是个伟大的事业。
再把之前的一段内容摘回来作为这一次思考的结束。
可能有人会想象,会不会有一天,软件的需求都不需要人类去定义,直接由人工智能来根据已知或挖掘的社会问题来自动生成需求并最终生成程序?
我相信未来可能会有人提出类似的概念并作出尝试,但是,我也不知道怎么描述,只能说人类科技的快速发展并不意味着未来人类的大脑只需要有一个乒乓球那么大就够了,人类在解决了自身社会问题后接下来所要面对的可能是更艰难的任务。如果人类为了免去一些思考而让机器产生了自主思维,这是一个很未来,很科幻的概念,而在现在的概念里,我只认为:程序帮助人类完善需求并最终将需求所需要的程序功能自动实现,已经是自动编程的终极阶段。
目前绝大多数的软件需求,离全自动化编程的实现肯定还有很长一段时间,我们没必要去评估这段时间到底多长,但在平时的编程开发工作中,有必要让自己始终保持警惕,时刻反省自己是否成为了一个很忙而又低效的人。不要忽略一个个细分场景的自动化给自己带来的效率提升,更不要放弃思考对各个自动化场景的融合,那是质变的捷径。