從面向對象編程語言PHP轉到Go時的一些疑惑?

在這里插入圖片描述

前言

1、php中面向對象編程時 與 Go中的區別?
2、php中最常使用laravel框架,不用過多關注依賴注入和反射,在go中又該如何使用呢?是 舍棄?
本文是一個系統化梳理,幫助從 語言哲學 → 依賴注入在 Go 的現狀 → 面向對象 + 接口編程的平衡 → 實踐建議 → 示例 → 通用方案 全鏈條理解。


🧠 一、Go 與 PHP(Laravel)在依賴注入/面向對象的核心區別

Laravel/PHPGo
語言風格強面向對象 + 動態語言面向接口 + 靜態語言 + 組合
容器/IOC有完整 IOC 容器,支持反射注入原生無 IOC,推薦組合/顯式依賴注入
DI 方式注解/反射自動注入通常是構造函數注入或 wire 靜態生成
優先級靈活(犧牲編譯時安全)可讀性+可維護+編譯期安全

Go 社區非常推崇:

? 顯式依賴(explicit dependency)
? 簡單組合(composition over inheritance)
? 少用反射(性能、調試可讀性)
? 在需要時用接口解耦,而非一上來就抽象


🛠 二、在 Go 中:常用的依賴注入方式

(其實我之前有一篇文章專門講解了Go中依賴注入的幾種方式,很詳細,可以直接點擊跳轉)

DI 方式特點
構造函數注入(constructor)推薦,簡單,編譯期安全,可讀性強
手動 new + 參數傳遞小項目最簡單
google/wire靜態生成依賴圖,保持編譯期安全,全局統一管理,推薦
Uber dig/fx基于反射的容器,更靈活,缺點是運行期出錯難排查
單例模式/once保證全局唯一實例,但全局狀態過多會降低可測試性

🧩 三、那為啥 wire / fx 常常“不爽”?

1、Go 是靜態強類型語言:寫 wire 需要明確依賴樹,一旦結構變復雜,需要頻繁維護 wire.go

2、工具層復雜度 > 實際收益:小項目用 wire 反而增加復雜度,不過我還是推薦wire,因為可以全局統一管理

3、反射容器(fx/dig) 運行期報錯難調,和 Laravel 的自動注入體驗完全不同

4、Go 的哲學:推薦通過“組合” + “接口”來解耦,而不是依賴大而全的 IOC 容器


? 四、可行的 Go 項目結構實踐思路

簡單總結:面向對象編程沒錯,但不要重度依賴 IOC,而是:

  • ? 保留面向對象/接口解耦

  • ? 使用構造函數注入(最小依賴)

  • ? 小規模可以直接手動 new

  • ? 大項目用 wire,但只生成頂層 main 初始化,不要全項目到處 wire

  • ? 不鼓勵到處寫單例,避免隱式依賴

📦 五、示例對比

🎯 示例一:簡單手動構造注入(推薦)

type UserService struct {repo UserRepository
}func NewUserService(repo UserRepository) *UserService {return &UserService{repo: repo}
}type UserRepository interface {FindByID(id int) (*User, error)
}// 在 main.go 或組裝層:
repo := NewMysqlUserRepository()
service := NewUserService(repo)user, _ := service.repo.FindByID(1)

? 好處:簡單明了,可測試(可以傳 mock)


🎯 示例二:wire 方式(靜態依賴注入)(推薦)

1、定義 provider
var ProviderSet = wire.NewSet(NewMysqlUserRepository,NewUserService,
)
2、wire.go
// +build wireinjectfunc InitializeUserService() *UserService {wire.Build(ProviderSet)return nil
}
3、編譯時生成 wire_gen.go

缺點:復雜依賴樹需要寫很多 providerSet;一旦重構容易出錯
優點:全局統一管理,整體依賴關系也是清晰明了


🎯 示例三:Uber fx/dig(運行時容器)

func main() {app := fx.New(fx.Provide(NewMysqlUserRepository),fx.Provide(NewUserService),fx.Invoke(func(s *UserService) {// 使用 s}),)app.Run()
}

缺點:更像 Laravel,但出錯在運行時;優勢:大規模項目靈活

🎯 示例四:單例(global instance)

var once sync.Once
var globalService *UserServicefunc GetUserService() *UserService {once.Do(func() {repo := NewMysqlUserRepository()globalService = NewUserService(repo)})return globalService
}

缺點:測試困難,可讀性差;只在確實需要全局唯一時用(如配置)


🌱 六、面向對象 + 接口編程在 Go 的平衡

  • ? 保留接口解耦(適合測試、替換實現)

  • ? 保留面向對象設計(有狀態的 service struct)

  • ? 不推薦重度依賴注入容器,可以用wire在頂層管理

  • ? Go 推薦:顯式依賴(構造注入) + 組合(組合多個 service)

🧩 七、常用通用做法

層級建議
main.go手動組裝依賴(或 wire 初始化一次)
service定義需要的依賴,用構造函數注入
repository定義接口,實現具體實現
config/log/db可做單例,或通過注入

? 八、我的建議總結

  • ? 保留面向對象寫法(service struct + methods)
  • ? 接口用于解耦,不要一開始就抽象一堆沒用的接口
  • ? 小項目手動 new / 構造注入即可
  • ? 大項目 wire 只負責初始化根依賴樹
  • ? 不要 over-engineering,Go 社區推崇簡潔
  • ?? 全局狀態少用,保持可測試性

? 后續:

下一篇我將說明講解go中如何使用wire來在頂層進行依賴管理(代碼示例說明),點擊即可直達

還有:go中使用wire來在頂層進行依賴管理時,如果出現 跨模塊依賴引用、循環依賴的問題,要如何解決呢(代碼示例說明),點擊即可直達

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/88426.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/88426.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/88426.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Vue3中使用konva插件動態制作海報以及可在畫布上隨意移動位置

1、下載konva插件 官網地址 npm install vue-konva konva --save2、在主文件中引入,如main.js import VueKonva from vue-konva; app.use(VueKonva);3、組件內使用,我現在的布局是左側是畫布,右側是相關設置(顏色、標題等&#…

政安晨【開源人工智能硬件】【ESP樂鑫篇】 —— 在macOS上部署工具開發環境(小資的非開發者用蘋果系統也可以玩樂鑫)

政安晨的個人主頁:政安晨 歡迎 👍點贊?評論?收藏 希望政安晨的博客能夠對您有所裨益,如有不足之處,歡迎在評論區提出指正! 前言 開源人工智能硬件會給你帶來無限可能,玩開源硬件,環境和工具少…

Vue3 學習教程,從入門到精通,vue3學習中的JavaScript ES6 特性詳解與案例(5)

vue3學習中的JavaScript ES6 特性詳解與案例 ES6(ECMAScript 2015)是 JavaScript 的一個重要版本,引入了許多新特性,極大地提升了語言的表達能力和開發效率。本文將詳細介紹 ES6 的主要特性,包括 let 和 const 命令、變…

深度學習模型1:理解LSTM和BiLSTM

深度學習模型1:理解LSTM和BiLSTM 因為最近科研復現論文中需要了解單向LSTM和雙向LSTM,所以就學習了一下LSTM的基本原理,下面孬孬帶著大家一起學習一下,感謝大家的一鍵三連 一、RNN 因為談到LSTM,就必不可少的會考慮RNN…

[論文閱讀] 軟件工程 | 一篇關于開源許可證管理的深度綜述

關于開源許可證管理的深度綜述 論文標題:Open Source, Hidden Costs: A Systematic Literature Review on OSS License ManagementarXiv:2507.05270 Open Source, Hidden Costs: A Systematic Literature Review on OSS License Management Boyuan Li, Chengwei Liu…

Qt懸浮動態

粉絲懸浮動態,及抽獎程序#include "masklabel.h"MaskLabel::MaskLabel(int pos_x,QString fans_name,QWidget*parent):QLabel(parent) {this->setAlignment(Qt::AlignHCenter);//設置字體居中this->setStyleSheet("color:white;font-size:20px…

深入拆解Spring思想:DI(依賴注入)

在簡單了解IoC與DI中我們已經了解了DI的基本操作,接下來我們來詳解DI。(IoC詳解請看這里)我們已經知道DI是“你給我,我不用自己創建”的原則。現在我們來看看Spring是如何實現“給”這個動作的,也就是依賴注入的幾種方式。 Spring主要提供了…

Arcgis連接HGDB報錯

文章目錄環境癥狀問題原因解決方案環境 系統平臺:Linux x86-64 Red Hat Enterprise Linux 7 版本:6.0 癥狀 Arcgis連接HGDB報錯: 無法連接到數據庫服務器來檢索數據庫列表;請檢查服務器名稱、用戶名和密碼信息,然后…

Android 應用常見安全問題

背景:OWASP MASVS(Mobile Application Security Verification Standard 移動應用安全驗證標準)是移動應用安全的行業標準。 一、MASVS-STORAGE:存儲 1.1 不當暴露FileProvider目錄 配置不當的 FileProvider 會無意中將文件和目錄暴露給攻擊者…

Netty的內存池機制怎樣設計的?

大家好,我是鋒哥。今天分享關于【Netty的內存池機制怎樣設計的?】面試題。希望對大家有幫助; Netty的內存池機制怎樣設計的? 超硬核AI學習資料,現在永久免費了! Netty的內存池機制是為了提高高并發環境下的內存分配與回收效率…

Python 項目快速部署到 Linux 服務器基礎教程

Linux的開源特性和強大的命令行工具使得部署流程高度自動化,可重復性強。本文將詳細介紹如何從零開始快速部署Python項目到Linux服務器。 Linux系統因其穩定性、安全性和性能優化,成為Python項目部署的首選平臺。無論是使用flask構建Web應用、FastAPI創…

SQL Server通過CLR連接InfluxDB實現異構數據關聯查詢技術指南

一、背景與需求場景 在工業物聯網和金融監控場景中,實時時序數據(InfluxDB)需與業務元數據(SQL Server)聯合分析: 工業場景:設備傳感器每秒采集溫度、振動數據(InfluxDB),需關聯工單狀態、設備型號(SQL Server)金融場景:交易流水時序數據(每秒萬條)需實時匹配客…

機器學習詳解

## 深入解析機器學習:核心概念、方法與未來趨勢機器學習(Machine Learning, ML)作為人工智能的核心分支,正深刻重塑著我們的世界。本文將系統介紹機器學習的基本概念、主要方法、實際應用及未來挑戰,為您提供全面的技術…

汽車間接式網絡管理的概念

在汽車網絡管理中,直接式和間接式管理是兩種用于協調車載電子控制單元(ECUs)之間通信與行為的機制。它們主要用于實現車輛內部不同節點之間的協同工作,特別是在涉及網絡喚醒、休眠、狀態同步等場景中。### 直接式管理直接式網絡管…

npm : 無法加載文件 D:\Node\npm.ps1,因為在此系統上禁止運行腳本。

npm : 無法加載文件 D:\Node\npm.ps1,因為在此系統上禁止運行腳本。 安裝高版本的node.js,可能會導致這個問題, 腳本的權限被限制了,需要你設置用戶權限。 get-ExecutionPolicy set-ExecutionPolicy -Scope CurrentUser remotesig…

搜索算法講解

搜索算法講解 深度優先搜索-DFS P1219 [USACO1.5] 八皇后 Checker Challenge 一個如下的 666 \times 666 的跳棋棋盤,有六個棋子被放置在棋盤上,使得每行、每列有且只有一個,每條對角線(包括兩條主對角線的所有平行線&#xff…

深度學習---Rnn-文本分類

# 導入PyTorch核心庫 import torch # 導入神經網絡模塊 import torch.nn as nn # 導入優化器模塊 import torch.optim as optim # 導入函數式API模塊 import torch.nn.functional as F # 導入數據集和數據加載器 from torch.utils.data import Dataset, DataLoader # 導入NumPy…

20250709解決KickPi的K7開發板rk3576-android14.0-20250217.tar.gz編譯之后刷機啟動不了

【整體替換】 Z:\20250704\rk3576-android14.0\rkbin清理編譯的臨時結果: rootrootrootroot-X99-Turbo:~$ cd 14TB/versions/rk3576-android14.0-20250217k7/ rootrootrootroot-X99-Turbo:~/14TB/versions/rk3576-android14.0-20250217k7$ ll rootrootrootroot-X99-…

怎么創建新的vue項目

首先,新建一個文件點文件路徑,輸入cmd

CIU32L051系列 DMA串口無阻塞性收發的實現

1.CIU32L051 DMA的通道映射由于華大CIU32L051的DMA外設資源有限,DMA只有兩個通道可供使用,對應的通道映射圖如下:2.UART對應的引腳分布及其復用映射CIU32L051對應的UART對應的引腳映射圖如下,這里博主為了各位方便查找,就直接全拿…