為什么又要造一個叫 Latke 的輪子
框架
使用框架的好處很多,它規范了我們的開發方式,減少了出錯的可能性,讓我們可以更快地完成開發目標,后續維護也可以有章可循;使用框架的弊端也很明顯,它束縛了我們,離開熟悉的框架進行開發我們可能會手足無措,它讓我們身陷其中。但無論如何,我們是離不開框架的,多認識幾種框架是沒錯的,Java Web 領域更是如此(選擇很多,同時也很少)。
到目前為止,我所認識的框架無一不例外都是以 class 作為實體類型的,為什么會這樣?為什么不能以其他形式(例如 map)作為實體載體?我覺得這些問題很值得討論(雖然以前可能已經討論過無數次)、很值得進行實踐。
為了把這個“想法”表達清楚,我們先看看一直以來在應用開發領域熱議的一些話題,最后再看看“想法”結晶——Latke 這個輪子是否能跑。
類型
在討論編程語言的時候,我們經常會聽到如“XXX語言不是類型安全的”,“XXX是動態語言,編程時檢查不了類型錯誤”等等此類。在過去(10 多年以前吧)這可能真的是一個“缺陷”, 但在今天來看,弱類型動態語言在應用開發領域(不是系統開發領域)越來越受歡迎,并且其他一些編程語言也在做類似的語法糖。
我想最大的原因就是弱類型語言在代碼修改時更快捷、成本更低,盡管我們現在使用的 IDE 重構輔助能力很強,可一旦實體模型發生字段變化,相關的修改也是夠頭疼的(特別是應用間交互的 DTO,修改成本瞬間飆升)。
當然,弱類型的缺點也是顯而易見的,就是除了開發者本人,其他人很難搞清楚(只看代碼片段)這個變量到底是什么,到底包含了什么字段,要徹底搞清楚只能通過通讀相關程序代碼 (如果有準確的文檔就方便多了)。無論如何,現如今很多應用開發都是選擇弱類型語言,并且已經得到了廣泛運維驗證(PHP、Node.js)。
JSON
近些年,JSON 無疑已經成為了數據載體的一個標準,幾乎所有編程語言、開發框架、存儲系統都支持 JSON 格式,最重要的是 JSON 是在瀏覽器端默認支持的結構化數據的方式。
在服務器端,使用 JSON 的地方(或者說和 JSON 相關的開發)也越來越多,POJO(實體對象/Entity)和 JSON 相互轉換無時不在發生:前端提交請求,參數是 JSON 格式,控制器接到請求后將 JSON 實參轉為 Java POJO,操作這個對象、生成響應(可能也是一個 JSON),最終返回前端,完成這次請求處理。在這個過程中,至少包含了兩次 JSON 和 POJO 的相互轉換,雖然有很多工具(例如 Jackson)能夠幫助我們完成 JSON-POJO 映射,但是這樣做的副作用也很明顯:需要再學習一個工具(要能夠正確使用它);額外的性能開銷(有時很小,但有時很巨大);代碼看上去怪怪的(不自然,工程化的“模型變換”)。
JSON 的確是好(簡單有效,沒有過度設計),但為什么不能從前到后的使用 JSON 呢?
ORM
將 POJO 持久化到關系型數據庫的過程就是 ORM。但因為存在阻抗不匹配的問題,所以再優秀的 ORM 方案也是存在問題的(性能問題、復雜查詢問題),在解決這類問題的時候,通常做法都是直接寫 SQL。從 ORM 實際實現上看,xBatis 的思路比 JPA 系更正確一些,但同時也略顯繁瑣了一些(需要定義 mapper.xml)。
數據庫表是二維的,數據總是可以轉為鍵值對集合/map 的(JDBC 結果集接口就是這樣干的),反之亦然。一個查詢 SQL 返回的結果集可以很容易就轉換為 map,復雜的是將這個 map 轉換為 POJO(嵌套的實體必須根據嵌套元信息才能完成映射)。
言至此,我們肯定會問一個問題:為什么不能直接使用 map 呢?
領域建模
前些年,“領域建模”這個詞非常流行,任何設計方案都要帶上這頂帽子才好意思和別人打招呼。那些年,要解決“用戶登錄”都要精心建模:
“User 類必須有。”
“嗯,最好抽象出個 IUser 接口。”
“既然都有接口了,再整個抽象基類吧。”
“嗯,很專業,成體系。”
“呃,等等,login 接口放 IUser 里吧?還是放 UserService 里?”
“放 service 里,大家都這么干的,放 user 里 Spring 好像不支持吧。”
最終,一個完美的 Java 航母應用開發完了,它確實能夠航行,但是要換個螺絲或者加個床位的時候:“等我找下設計圖,嗯,換螺絲要拆掉 A~Z 這幾個地方就能看見要換的螺絲了,加床位可能不行,哦,嬰兒床應該可以”。
這一切大部分都歸咎于一開始我們討論的:類型。類型一旦固定,就真的固定了,無論我們設計的抽象體系有多圓,最終都無法做到無損擴展(不可能真正達到開閉原則),因為所有的精密抽象都是存在泄漏的,面向類類型的編程范式在解決問題時不夠直接,并且很難修改。
進一步成 Latke
把上面討論的內容揉在一起,揉著揉著,居然變成了一個輪子——Latke(項目托管在 GitHub 上,歡迎 Star/fork)。
前后端分離
類似 Tapestry、Wicket、JSF、GWT 的思路都是反前端的,前端該是什么樣就是什么樣(HTML/JS/CSS),當然,服務器端的模板引擎還是需要的(比如 FreeMarker)。最終前端選擇什么框架、工具絕對是前端開發決定,和后端沒什么關系。
只有 JSON
請求實參 JSON 對象(很少情況是其他格式)傳到控制器后,不用轉為 POJO(因為我們壓根沒這個),直接操作這個 JSON(修改字段值、增減字段),并且可以很容易就將它持久化到數據庫中了。大多數時候都不用寫 SQL,少數時候就獲取數據庫連接,JDBC 吧。
有 Schema
雖然從前到后都是使用 JSON,但也不用擔心數據結構混亂,因為表結構和 JSON 的映射是有配置文件定義的,可以通過這個結構定義生成建表 SQL,也可以通過已有的數據庫表生成這個結構定義。
基于 Servlet
另起爐灶(比如 Play)無論是對做輪子還是對用輪子的人來說成本都太高了,而且 Servlet 對 HTTP 的抽象還是比較適當的,這個真沒必要再弄一套,Latke 輪子實在碾不過去的地方就直接操作 Request 和 Response 吧,這個大家都會。
多種 DB
支持多種數據庫的 JSON 化 CRUD,要更換數據庫(雖然真實世界很少發生)很方便:有數據導出/導入工具,無痛數據遷移(比如從 GAE Datastore 遷移到 MySQL)。
插件
可以在不改動任何一行現有代碼的前提下添加新功能,而且這個新功能是完整的(前端后端都有),可以很容易就集成到現有界面中的任何地方。
各種工具
Cache、Event、Cron、IoC、i18n、HTTP client、mail、themes 已經內置,雖不敢說每個服務功能如何強大,但我敢說對大部分的應用場景已經足夠使了,并且輪子本身的第三方依賴也是精挑細選的,這些工具加一起真的足夠了。
性能
從實現上看是 Servlet 的薄封裝,理論上和直接使用 Servlet 性能差距不會太大,實際上我們也是進行過壓測的,結果顯示沒有性能問題。
再進一步
“用上 Latke 輪子后開發效率提升一大截,但還是嫌前進太慢,怎么破?”
這已經不是輪子圓不圓的問題了,這是造輪子時使用的材料問題(風火輪和我們汽車輪子一樣圓吧,可實際上速度不是一個量級的,還可以當作武器,另外,這個還和使用的人有關吧)。
Java 就這樣了,我們既然用了就說明我們已經接受它了,既然接受了就得忍讓著點,最終忍不了就可以像王垠大神一樣。不過對于我們凡人來說,比較切實可行的做法是換個編程語言,種種跡象表明,Node.js 在應用開發領域已經風生水起。
最后
前面說了一大推來證明 Latke 是圓的,要是你不相信,請看下《Latke 快速上手指南》,里面有個 demo;要是你還不相信,就親自試用吧 ;-p
參考
- </li>
- </li>
-
《黑客與畫家》
</li> -
</li>
</ul>
來自:http://www.oschina.net/news/53199/b3log-latke
本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!