如何站在開發者的角度理解框架的設計思想?

来源:https://www.cnblogs.com/wangzhongyang/archive/2023/01/03/17022425.html
-Advertisement-
Play Games

有問必答 最近有好多讀者私信我,為什麼選擇GoFrame做電商項目的開發? 原因很簡單: 因為我司是用GoFrame做電商業務開發的,而且我司同事基本都是PHP轉Go的。GoFrame可以說是非常適合PHPer轉Gopher的開發框架。 在入職我司之前,我有使用Gin和go-micro框架,目前也正 ...


有問必答

最近有好多讀者私信我,為什麼選擇GoFrame做電商項目的開發?

原因很簡單:

因為我司是用GoFrame做電商業務開發的,而且我司同事基本都是PHP轉Go的。GoFrame可以說是非常適合PHPer轉Gopher的開發框架。

在入職我司之前,我有使用Gin和go-micro框架,目前也正在學習go-zero。

不管是開發語言還是開發框架,都服務於我們所做的業務,拋開業務去聊語言或者框架都是沒有意義的。

使用GoFrame做開源項目的另一個原因是:想體驗一下V2版本的新特性,自己的項目怎麼做自己能完全說了算,沒有歷史包袱。

前言

讓開發者更好的做到“模塊內部高內聚,模塊之間松耦合”,是我認為GoFrame V2設計的精髓。

用GoFrame開發商業項目已經很長時間,發現GoFrame的版本更新比較快,社區也非常的活躍。

因為歷史原因,我之前一直用V1.16版本做商業項目的開發,雖然個人有比較強的意願升級到V2。

但是考慮到項目穩定性及開發成本等等原因,商業項目並未升級。這可能也是很多小伙伴面臨的問題。

受到鼓勵

正好前段時間,分享了自己的開源項目【Go WEB進階實戰】基於GoFrame搭建的電商前後臺API系統
受到了大家的關註和支持,GoFrame的作者也在點贊轉發,更受鼓勵。

更重要的是:收到了社區里很多小伙伴的建議,最多的建議就是建議我使用V2版本,因為提供了很多新特性,可以更好的實現需求,穩定且高效。

決定升級

所以,我決定把我開源的項目從V1.16.x版本,升級到最新的V2.2.0版本,踩一下升級的坑,享受一下升級後的快樂。

歡迎小伙伴們加入到我的開源項目中:電商前後臺系統API,目前V1版本已經收尾,包括電商項目的常用功能,開發了120多個介面。

一起參與

V2版本在開發過程中,目前已經開發了30多個介面,計劃這個月內開發完畢,也開源出去。歡迎小伙伴們參與共建,也歡迎閱讀我的源碼,多提寶貴建議:

V2版本GitHub地址

因為內容比較長且硬核,所以我決定分兩篇文章分享:

  1. 這篇文章重點:介紹GoFrame V2的新特性,和V1相比有哪些優勢?最大的變化是什麼?

  2. 下一篇文章會分享一下:我從V1升級到V2的踩坑之旅,相信對很多小伙伴都有幫助。

這個經歷實屬不易,希望小伙伴們可以點贊、關註、轉發一波。

適合看的人群

  1. 掌握Go基礎後,想用成熟框架開發項目的伙伴,建議讀完我的文章之後,直接使用GoFrame最新的V2版本實戰開發
  2. 目前在用V1版本,有意願但是沒有大量精力學習V2新特性的伙伴,擔心升級問題太高不敢貿然升級的伙伴們。
  3. 想提高自己學習新知識效率的小伙伴,歡迎復刻我的這種實踐方式。

站在開發者的角度

不管你是哪種人群,都建議先花時間仔細閱讀官方文檔,尤其是 框架介紹這部分。

區別於官方文檔,這篇文章會結合我自己的經驗,站在框架使用者的角度,幫大家更快更好的理解Goframe V2版的設計思路,基於V2版本如何更好的進行商業項目的開發。

踩的坑

在我升級版本的過程中發現:一定要先瞭解清楚V2的新特性,然後再從V1升級到V2,否則升級到一半會出現無從下手的問題:

  1. 因為通過V2版本的CLI工具生成的dao、model,和V1版本是不一致的:廢棄了gmvc模塊等,也引入了新的模塊。

  2. V2版本支持gf gen service的方式生成service層,統一我們介面邏輯的實現方式,引入了logic層和service層的概念

結合自己的升級經歷,分享給大家學習GoFrame V2必知必會的知識點:

必知必會

  1. 項目工程結構發生了變化,且需要按照V2的標準來,因為gf工具生成代碼的目錄結構發生了改變,更重要的:V2官方建議的目錄結構也是我們踐行"高內聚低耦合"比較好的工程目錄結構。

  2. gf gen dao除了會像V1一樣生成dao層和model層,還會另外生成do層和entity層

  3. V2版本的目錄結構實踐了業務模型和數據模型解耦的思想(也是我認為非常贊的地方)

  4. V2相比於V1會出現方法或者模塊廢棄的情況,比如廢棄了gmvc耦合模塊,未來不再進一步支持。同時也為我們提供了更好的實現方式。

  5. V2有點編寫“微服務”的意思了,需要服務註冊:controller調用一個或多個service實現具體的業務邏輯;但是複雜的業務邏輯又不是在service中實現的,為瞭解耦,V2版本引入了logic目錄,用於編寫和復用複雜的業務邏輯。在logic中註冊服務,在service中通過介面方式規範logic層要實現的方法。

重中之重

下麵再介紹一下我花了很長時間才消化的知識點:

dao代碼生成(很重要)

gf gen dao

在業務項目中,官方推薦使用dao/do/entity的方式操作資料庫,這些文件都是通過開發工具自動生成的,由開發工具統一維護。

區別於V1版本,V2版本引入了do的概念,為什麼這麼設計?

在這裡我只說結論,文章最後會附上官方鏈接:

  1. dao層用於數據訪問,這是一層抽象對象,用於和底層資料庫交互,僅包含最基礎的 CURD 方法

  2. model層是結構模型,是數據結構管理模塊,管理數據實體對象,以及輸入與輸出數據結構定義。

    2.1 model中的do是領域對象,用於dao數據操作中業務模型與實例模型轉換,由工具維護,用戶不能修改。

    2.2 model中的entity是數據模型,數據模型是模型與數據集合的一對一關係,由工具維護,用戶不能修改。

後面我會帶著大家用實例講解

服務介面生成(更重要)

gf gen service

服務介面是非常重要的知識點,也是我認為在cli工具支持方面和V1版本最大的區別:

為了降低業務項目內部模塊間的耦合,框架將模塊間的依賴抽象為了介面,由internal/service包維護。internal/service可以由開發者自定義維護介面,也可以通過internal/logic業務封裝的代碼按照一定規則自動生成介面代碼文件。

實踐出真知

看10遍文檔,都不如一次動手實踐。建議大家和我一起操練起來,歡迎復刻:

我的思路是這樣:

  1. 下載官方的示例項目,學習一下官方是怎麼寫的。

  2. 給自己提需求,參考官方的實現方式,實現自己的業務場景。

  3. 我會帶著大家實現經典的電商場景:添加和查詢商品信息。

1. 下載運行官方示例的GitHub

官方示例GitHub

1.1 下載部署好項目之後,啟動:非常順滑的就啟動成功了:

1.2 請求介面,驗證試一下DB是否連接正常。

1.3 查詢資料庫,也是有值的。

驗證環境無誤,下麵開始帶著大家參考官方示例實現自己的需求,進而更好的理解V2版本新特性和工程實踐。

2. 基於V2編寫商品管理

我們按照官方建議的工程方式去實踐,看看會不會踩坑:

2.1 創建goods表如下:

2.2 通過gf gen dao生成dao和model

初次嘗試,失敗,原因是沒有修改hack目錄下的config.yaml配置文件。

註意:和V1不同,官方說hack目錄的作用是工具腳本,存放項目開發工具、腳本等內容。例如,CLI工具的配置,各種shell/bat腳本等文件。所以我們就不要像V1一樣把cli工具的配置文件也寫到manifest/config目錄中了。

2.3 搞定,成功生成。

小技巧,如果我們不指定tables,則生成所有表對應的數據。我是比較喜歡這麼操作:因為能避免自己改了多個tables,但是在配置文件中漏寫了某個tables導致意料之外的問題。

下麵開始正式擼代碼了:

我會先按照大家容易理解的方式進行編寫,文章最後我會分享實踐經驗:按照什麼順序編寫各個模塊的代碼是比較科學的。

2.4 首先我們實現api層,定義請求和響應的結構體

2.5 我們在cmd中註冊Goods相關的路由

2.6 我們發現註冊路由時,controller.Goods飄紅,原因是我們還沒有編寫這個方法。

我們參考示例代碼去編寫controller層:

我們發現右側的示例項目,方法內部調用了service中的方法,但是我們目前還沒有定義service,怎麼辦?

我們先點擊示例項目中的user.go,查看一下service中都定義了什麼:

經過查閱文檔得知:

我們需要通過編寫logic層實現業務邏輯,通過配置goland插件,自動生成service代碼。

這要是官方建議我們的最佳實踐:

2.7 導入官方提供的xml文件(只需要配置一次)

xml文件地址

強烈建議大家這麼操作,經過這個配置在我們編寫logic層代碼的時候,service能自動生成介面定義文件。

當然也可以不配置,只是每一次在開發/更新完成logic業務模塊後,都需要手動執行一下 gf gen service 命令。太麻煩了!!!

2.8 我們參考右側的示例 編寫商品goods的logic代碼,處理業務邏輯:

2.9 經測試我發現:在編寫logic邏輯後,就自動在service層生成了對應的goods文件和方法,非常方便。

2.10 我們再繼續寫添加商品邏輯和查看商品邏輯

我們發現:在logic層編寫完添加商品邏輯後,在右側的service層自動生成了代碼。

2.11 細心的同學可能發現了service層的RegisterGoods方法,這是幹嘛用的呢?

答案是:我們要在service層生成RegisterXX()方法後,在對應的業務模塊中加上介面的實現註入。

小提示:該方法每個業務模塊加一次即可。

建議大家在編寫完第一個logic方法後(或者說service層生成了RegisterXX方法後):

  1. 就在logic層的init函數中實現服務的註冊;

  2. 然後去查看logic.go文件是否添加了相關的依賴,沒有的話也可以手動添加一下;

要成良好的編碼習慣,少出bug。

2.12 我們查看logic目錄下的logic.go文件,發現已經自動添加了我們本次編寫的goods相關的import:

這個文件的作用是:將介面的具體實現,在程式啟動時執行註冊。

好了,logic和service到此結束,我們已經完成了業務邏輯的編寫。

內容不少,大家可以上劃再看一遍這部分內容,消化吸收一下。

2.13 咱們回過頭來,繼續編寫controller層的代碼:

我們參考官方提供的controller/user.go 實現了我們自己的 controller/goods.go的添加商品方法:

2.14 到這裡,我們已經完成了新需求的編寫,啟動服務查看一下效果:

很OK,已經看到了對應的介面。

編碼完畢,測試一下:

我們請求介面,添加數據看一下:

在資料庫中也查看到數據:插入成功,流程走通!

反思回顧

按照上面這個流程走下來,雖然整體跑通了。我個人感覺還是比較混亂的。

我又花了比較長的時間消化吸收了官方文檔的工程實踐,結合我自己的經驗。

我們再來梳理一下V2項目的編寫流程,我的建議是這樣的

整理流程

  1. 設計表結構

  2. 使用gf gen dao生成對應的dao/do/model目錄代碼

  3. 編寫api層:定義「業務模塊」的數據結構,提供對外介面的輸入/輸出數據結構

  4. 編寫model層:定義「數據模塊」的數據結構,提供對內的數據處理的輸入/輸出數據結構

  5. 編寫logic層,自動生成service層代碼。(通過配置goland File Watcher自動生成,也可以通過gf gen service手動執行腳本生成,強烈建議前者)

  6. 在service層代碼生成RegisterXX()方法後,在對應的logic模塊註冊服務(每個模塊只需要寫一次)

  7. 編寫controller層,接收/解析用戶輸入的參數,調用service層的服務。

  8. 註冊路由,對外暴露介面,比如這個項目是編寫cmd.go文件。

  9. 在main.go中 加入一行 _ "project-name/internal/logic" (只需寫一次)

  10. 在main.go中加入一行 _ "github.com/gogf/gf/contrib/drivers/mysql/v2" (如果你使用的是mysql;只需寫一次)

關鍵流程

  1. 上面的步驟只有3~8是每次開發新需求都需要的
  2. 步驟1、2設計表結構和自動生成代碼很簡單,涉及到新增表或者修改表時才需要
  3. 步驟9、10在創建項目時編寫一次即可

再次實操

我按照上面這個步驟,編寫了查詢商品邏輯,整體還是非常順滑的:

小伙伴們也動手實踐吧,歡迎star fork我的開源項目:https://github.com/wangzhongyang007/goframe-shop-v2

帶著問題學習

我在編寫商品管理需求的時候有些疑惑:

為什麼要定義兩遍數據結構呢?在api層定義了一遍,在model層又定義了一遍,我寫了兩遍重覆的結構體,意義何在呀?

我靜下心來想想,這個設計還是值得好好推敲的,我結合之前的項目經歷分享一下我的理解。拋磚引玉,小伙伴們有什麼理解歡迎在評論區留言。

之前遇到的問題

我們之前在在開發商品中心統一入庫時就遇到了難以維護的問題,原因就是業務邏輯和數據處理邏輯耦合在一起。

隨著業務的複雜度越來越高,項目維護成本越來越高,甚至達到了難以維護的程度。

我們是如何解決的呢?

解決辦法和GoFrame的數據模型和業務模型解耦,底層思想是一樣的:

我們把複雜的邏輯進行了拆分:定義了業務模塊和數據處理模塊。

「業務模塊」:只處理接收的參數,並不關心如何入庫和取值,按照「數據模塊」的要求,處理好前端傳入的數據,統一結構體傳遞給「數據模塊」即可。

「數據模塊」:不需要關心「業務模塊」的具體實現,定義了統一的入參標準,要求業務模塊按照自己的要求,統一傳入數據;數據模塊考慮的重點是如何高效的批量插入數據,如何高效的按需取值,並不需要關心多變的業務側需求。

升華一下

經過對冗餘模塊的拆解,梳理清楚了「數據模塊」和「業務模塊」的邊界,我們不僅解決了之前項目難以維護的問題,還提高了靈活對接客戶需求的能力。

結合自己的項目經歷和這次實踐V2版本的經歷,所以我開篇說:讓開發者更好的做到“模塊內部高內聚,模塊之間松耦合”,是我認為GoFrame V2設計的精髓。

好了,這篇文章就到這裡,硬核爆肝5千字,堅持更新實屬不易,歡迎大家點贊、評論、轉發。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 流程式控制制 用戶交互Scanner Scanner類可以實現電腦與人的交互。java.util.Scanner 是 Java5 的新特征,我們可以通過 Scanner 類來獲取用戶的輸入。 Scanner 類的 next() 與 nextLine() 方法獲取輸入的字元串,在讀取前我們一般需要 使用 ...
  • 同步和非同步 同步和非同步是指程式的執行方式。在同步執行中,程式會按順序一個接一個地執行任務,直到當前任務完成。而在非同步執行中,程式會在等待當前任務完成的同時,執行其他任務。 同步執行意味著程式會阻塞,等待任務完成,而非同步執行則意味著程式不會阻塞,可以同時執行多個任務。 同步和非同步的選擇取決於你的程式需 ...
  • 摘要 本文主要講述了一個 http request 請求從發出到收到 response 的整個生命周期,希望可以通過對整個流程的一個描述來梳理清楚五層網路協議的定義以及各層之間是如何協作的。 使用Golang發起一個HTTP請求 對於後端來說通過 http 請求來進行遠程調用是再尋常不過的事了,以 ...
  • 1. 拷貝和拷貝構造函數 拷貝和複製是一個意思,對應的英文單詞都是copy。對於電腦來說,拷貝是指用一份原有的、已經存在的數據創建出一份新的數據,最終的結果是多了一份相同的數據。例如,將 Word 文檔拷貝到U盤去複印店列印,將 D 盤的圖片拷貝到桌面以方便瀏覽,將重要的文件上傳到百度網盤以防止丟 ...
  • 家居網購項目實現013 以下皆為部分代碼,詳見 https://github.com/liyuelian/furniture_mall.git 32.功能30-會員不能登錄後臺管理 32.1需求分析/圖解 管理員admin登錄後,可以訪問所有頁面 會員登錄後,不能訪問後臺管理相關頁面,其他頁面可以訪 ...
  • 大家好,我是車轍,我的掘金小冊《SkyWalking:應用監控和鏈路跟蹤》已經上線啦,這是我的第一本電子書,歡迎大家訂閱。 整整好是9月的最後一天下午,能按耐住衝動的是少之又少,至於原因嘛你懂的。趕高鐵的準備趕高鐵,沒趕高鐵的也假裝趕高鐵。特別是開發同學,腦門上就差貼張紙條:別打擾我。 現在離跑路時 ...
  • 大多數開發者可能都用過 Postman,根據其官網的介紹:Postman 是一個用於構建和使用 API 的 API 平臺,簡化了 API 生命周期的每個步驟,提供更便捷的團隊協作,因此可以更快地創建更好的 API。這裡的 API,除了我們常用的 HTTP API 之外,還包括 Websocket(B ...
  • 一、前言 redis在我們企業級開發中是很常見的,但是單個redis不能保證我們的穩定使用,所以我們要建立一個集群。 redis有兩種高可用的方案: High availability with Redis Sentinel(哨兵) Scaling with Redis Cluster(分片集群) ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...