code-generate是一個(gè)通用的代碼生成工具,支持從各種元數(shù)據(jù),通過定義模板生成需要的代碼,減少低級(jí)重復(fù)的編碼工作。目前支持通過數(shù)據(jù)庫元數(shù)據(jù)生成業(yè)務(wù)對(duì)象、數(shù)據(jù)訪問對(duì)象等。
項(xiàng)目地址
gitee: https://gitee.com/wei772/code-generate
github: https://github.com/wei772/code-generate
使用方法
-
配置模板倉庫,在 src/resources/templateRepository 目錄下創(chuàng)建模板倉庫或使用現(xiàn)有模板倉庫,詳情參考entityDemo倉庫
-
運(yùn)行
mvn -U clean install生成code-generate.jar包 -
使用Java17+運(yùn)行jar包 或者單元測(cè)試TestCommandLineApplication或者 CommandLineApplication運(yùn)行
- 使用entity代碼生成工作類,并且使用jsonFileReader運(yùn)行(該方式主要用于測(cè)試,不建議實(shí)際使用)
編寫實(shí)體定義Json,參考definition.json
運(yùn)行jar包
Windows下建議使用Cmd,PowerShell下面腳本運(yùn)行有問題
java -jar code-generate.jar -Dtemplate.repository=entityDemo -Dgenerate.output=D:\source\code-generate\src\test\resources\generateResult -Dgenerate.basePackage=cn.cli -Dgenerate.author=liwei -Dgenerate.tags=mysql,jdbc -Dentity.reader=jsonFile -Dentity.reader.json.file=D:\source\code-generate\target\test-classes\entityGenerate\userDefinition.json
使用配置文件運(yùn)行jar包
java -jar code-generate.jar "-c=D:\source\code-generate\target\test-classes\config\json.properties"
- 使用JdbcFileReader運(yùn)行
創(chuàng)建數(shù)據(jù)庫和表
運(yùn)行jar包
java -jar code-generate.jar -Dtemplate.repository=entityDemo -Dgenerate.output=D:\source\code-generate\src\test\resources\generateResult -Dgenerate.basePackage=cn.cli.jdbc -Dentity.reader=jdbc -Dentity.names=user -Dentity.reader.jdbc.url=jdbc:mysql://localhost:3306/code_generate -Dentity.reader.jdbc.user=root -Dentity.reader.jdbc.password=123456
代碼生成的優(yōu)缺點(diǎn)
代碼生成的最大優(yōu)點(diǎn)就是減少低級(jí)重復(fù)的編碼工作。
但是也有不少缺點(diǎn)。
-
首先它第一次生成容易,一旦修改過,生成就會(huì)困難很多。如果不修改生成代碼可以減少影響
-
其次,尤其是比較重量級(jí)的生成容易促使開人人員直接使用生成的代碼,而不是根據(jù)實(shí)際需求去調(diào)整代碼
-
還有一個(gè)比較重大弊端,會(huì)隱藏架構(gòu)的垃圾設(shè)計(jì),給垃圾架構(gòu)打補(bǔ)丁。
-
比如一個(gè)實(shí)體生成幾十個(gè)相關(guān)類,如果要手寫只要是程序員就會(huì)拒絕這種垃圾架構(gòu),
但是如果有代碼生成可能就勉強(qiáng)能接受。但是這樣的架構(gòu)是難以修改的,生成代碼工具只會(huì)是溫水煮青蛙,還不如不要。 -
很多看起來很有用的技術(shù)都存在同樣的問題,比如依賴注入框架,很容易寫出有復(fù)雜的依賴的類而不自知。技術(shù)手段無法拯救垃圾的設(shè)計(jì),只會(huì)把問題隱藏的更深點(diǎn),變得更嚴(yán)重
-
代碼生成工具需要慎用,盡可能優(yōu)化架構(gòu)與設(shè)計(jì),實(shí)在沒辦法避免的重復(fù)勞動(dòng)才考慮使用。
測(cè)試驅(qū)動(dòng)開發(fā)
本項(xiàng)目使用測(cè)試驅(qū)動(dòng)開發(fā)的方法開發(fā)
效果與感受
流暢的組織所有開發(fā)活動(dòng)的技術(shù)
測(cè)試驅(qū)動(dòng)開發(fā)這種先寫測(cè)試再開發(fā)的方式很流暢。
- 不要絞盡腦汁再腦中、用文字還有圖去思考設(shè)計(jì),這種方法浪費(fèi)時(shí)間,想象力也無法有效發(fā)揮。
- 也不會(huì)一上來就編碼,編寫難以執(zhí)行代碼,代碼基本沒有設(shè)計(jì),想到哪寫到哪。
- 使用單元測(cè)試可以持續(xù)重構(gòu),一直保持設(shè)計(jì)和編碼變得更好的
自底向上
本項(xiàng)目中體會(huì)到測(cè)試驅(qū)動(dòng)開發(fā)是一種自底向上的設(shè)計(jì)和開發(fā)方式,從明確和細(xì)微的方向開始一直到最復(fù)雜的問題,直到完成最終目標(biāo)。
遇到新的并且復(fù)雜的事情,確實(shí)很難一下自頂向下給出比較完善設(shè)計(jì)方案,自底向上提供了一種一步一步解決部分問題,不斷集成最終解決所有問題的方式。
依次在各個(gè)層次編碼、設(shè)計(jì)、測(cè)試
測(cè)試驅(qū)動(dòng)開發(fā)能夠?qū)σ粋€(gè)概念在各個(gè)層級(jí)上都很好的測(cè)試、編碼和設(shè)計(jì),保證每個(gè)層次都最適合自己。例如targetLanguage就是從EntityType到Property以及Entity最后的CodeGenerate
從最高層到最低層測(cè)試。一旦那一層出現(xiàn)問題,只要看哪些測(cè)試用例異常都可以分析出哪里出問題,如果高層沒有問題,那么問題就是最底層沒有傳好值,或者改動(dòng)高層的值導(dǎo)致的。
然后targetLanguage相關(guān)設(shè)計(jì),就有了Entity更新targetLanguage,PropertyType也會(huì)更新targetLanguage的實(shí)現(xiàn),這能大大降級(jí)了調(diào)試時(shí)間
單元測(cè)試的代碼代碼量
單元測(cè)試的代碼與實(shí)現(xiàn)的代碼量差不多,某次統(tǒng)計(jì)代碼行,實(shí)現(xiàn) 1714、單元測(cè)試 1400 (使用 IDEA Statistic插件統(tǒng)計(jì))。
看起來增加了工作量,實(shí)際上卻不是。減少了調(diào)試的時(shí)間,而且代碼更加簡(jiǎn)潔,也是重構(gòu)的基礎(chǔ),極大了減少了bug量。大大減少了開發(fā)和維護(hù)成本
測(cè)試驅(qū)動(dòng)開發(fā)本質(zhì)
下面一些經(jīng)典數(shù)據(jù)的一些論述,涉及到測(cè)試驅(qū)動(dòng)開發(fā)本質(zhì)
《測(cè)試驅(qū)動(dòng)開發(fā) (Kent Beck) 》當(dāng)中有幾段話讓我印象深刻,體現(xiàn)了這種方法的核心作用
- 而我從書本上學(xué)到的卻恰好相反:“編碼為今天,設(shè)計(jì)為明天。”而測(cè)試驅(qū)動(dòng)開發(fā)看起來已經(jīng)徹底推翻了這一論點(diǎn): “為明天編碼,為今天設(shè)計(jì)。” 。
- 測(cè)試(Test)--自動(dòng)、具體、切實(shí)的測(cè)試。按一個(gè)鍵就可以讓測(cè)試運(yùn)行。具有諷刺意味的是測(cè)試驅(qū)動(dòng)開發(fā)不是一種測(cè)試技術(shù)(Cunningham
Koan)。 它是一種分析技術(shù)、設(shè)計(jì)技術(shù),更是一種組織所有開發(fā)活動(dòng)的技術(shù)。
《敏捷整潔之道:回歸本源》關(guān)于復(fù)式記賬的論述
- 會(huì)計(jì)師們?cè)?000年前發(fā)明了一條法則,并將其稱為復(fù)式記賬。每筆交易會(huì)寫入賬本兩次:在一組賬戶中記一筆貸項(xiàng),然后相應(yīng)地在另一組賬戶中記為借項(xiàng)。
這些賬戶最終匯總到收支平衡表文件中,用總資產(chǎn)減去總負(fù)債和權(quán)益。差額必須為零。如果不為零,肯定就出錯(cuò)了 - 復(fù)式記賬與TDD這兩種紀(jì)律是等效的。它們都具有相同的功用:在極其重要的文檔中避免錯(cuò)誤,確保每個(gè)符號(hào)都正確。
盡管編程對(duì)社會(huì)來說已經(jīng)必不可少,
但我們還沒有用法律強(qiáng)制實(shí)施 TDD。可是,既然編寫糟糕的軟件已經(jīng)造成了生命財(cái)產(chǎn)損失,立法還會(huì)遠(yuǎn)嗎?
步驟
首先編寫任務(wù)清單,一般包含設(shè)計(jì)想法、要實(shí)現(xiàn)用例、重構(gòu)任務(wù)等等,將TODO的事情要一個(gè)簡(jiǎn)單的文檔記錄,整個(gè)過程比較隨意,有價(jià)值的想法就記錄下來,完成之后將對(duì)應(yīng)的任務(wù)劃上刪除線。
然后是具體編寫過程
- 從任務(wù)清單中挑選任務(wù),針對(duì)任務(wù)編寫不通過的單元測(cè)試,包括無法編譯和運(yùn)行錯(cuò)誤的用例
- 使單元測(cè)試運(yùn)行通過
- 重構(gòu)現(xiàn)有代碼,使設(shè)計(jì)更佳。
每次寫代碼都重復(fù)這3個(gè)步驟,直到?jīng)]有需要完成的任務(wù)。
包結(jié)構(gòu)和主要類介紹
entity包
主要包含實(shí)體定義相關(guān)類 Entity、Property和EntityType。
entity.reader包
實(shí)體代碼生成讀取實(shí)體配置
目前支持的配置類型
- jsonFile ,從json文件中讀取配置的元數(shù)據(jù)
- jdbc ,使用jdbc從mysql與oracle等數(shù)據(jù)庫讀取元數(shù)據(jù)
template包
對(duì)應(yīng)模板引擎和模板實(shí)例
目前支持的模板引擎有
- velocity,使用詳情請(qǐng)參考 https://velocity.apache.org/engine/2.4.1/user-guide.html
param包
支持從配置文件中讀取參數(shù)
- 支持@file參數(shù),在文件里設(shè)置可以指定文件生成名
- 支持@folder,在文件里設(shè)置可以指定文件生成的目錄,一般配合output參數(shù)使用。
generate包
代碼生成核心類
- CodeGenerate,代碼生成的人口,讀取所有代碼生成相關(guān)參數(shù)
- CodeGenerateWork,真正去執(zhí)行代碼生成的工作類
- CodeGenerateWork具體實(shí)現(xiàn)類
- EntityCodeGenerateWork,通過實(shí)體配置讀取模板文件生成相關(guān)文件
浙公網(wǎng)安備 33010602011771號(hào)