从面向对象编程语言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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈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对应的引脚映射图如下,这里博主为了各位方便查找,就直接全拿…