实践出真知:myshop

169 阅读8分钟

MyShop 开发日志:从零开始的Go电商系统

嘿!让我跟你分享一下我开发这个简单Go电商系统的完整历程。作为一个从Java转Go的开发者,这个过程充满了挑战和收获。当然,有一些后端基础上手非常轻松。首先声明,我不是很厉害。

项目缘起

为什么要做这个项目?说实话,最开始是为了学习Go。我发现很多Go的教程都是Hello World级别的,要么就是特别复杂的微服务架构。作为一个刚入门Go的开发者,我需要一个中等复杂度的项目,既能覆盖常见的业务场景,又不会太过复杂。

电商系统是个很好的选择,因为它包含了:

  1. 用户认证 - JWT实现
  2. CRUD操作 - 商品管理
  3. 事务处理 - 订单创建
  4. 并发控制 - 库存管理
  5. 关联查询 - 订单商品

技术选型

说说技术选型的思考过程:

  1. Web框架:Gin 最开始在 Gin、Echo、Fiber 之间犹豫。最后选择 Gin 是因为:
  • 社区活跃度高
  • 文档完善
  • 性能优秀
  • 上手简单
  • 中间件丰富 ''
  1. 数据库:MySQL + GORM 为什么是MySQL?
  • 使用广泛,运维简单
  • 文档丰富
  • ACID支持好
  • 社区活跃

为什么用GORM?

  • 自动迁移很方便
  • 查询API友好
  • 事务支持好
  • 钩子机制强大
  1. 认证方案:JWT 考虑过session,但JWT的无状态特性更适合API服务:
  • 不需要存储session
  • 便于水平扩展
  • 客户端处理方便
  • 适合前后端分离

项目结构详解

采用了经典的三层架构,但做了一些调整:

目录结构是这样的:

/myshop
├── cmd/                    // 程序入口
├── internal/              // 内部代码
│   ├── handler/          // HTTP处理器
│   ├── model/            // 数据模型
│   ├── repository/       // 数据访问层
│   └── service/          // 业务逻辑层
└── pkg/                  // 公共代码

说实话,一开始我还想加入更多花哨的功能,比如Redis缓存、消息队列什么的。但后来想想,还是先把基础功能做扎实比较重要。毕竟,过度设计往往是项目的第一个坑。

还有就是,其实我没有删一些不用的代码,所有不方便传递,你知道的,写代码并不是一帆风顺。

开发过程中的一些思考

  1. 关于错误处理 最开始我是这样写的:
    if err != nil { return err }
    

后来发现这样不太好,因为:

  • 错误信息不够明确
  • 无法区分业务错误和系统错误
  • 调试困难

改进后:

if err != nil { return fmt.Errorf("创建订单失败: %w", err) }
  1. 关于事务处理 订单创建是个典型的事务场景,需要同时:
  • 创建订单记录
  • 扣减库存
  • 保证原子性

一开始我是手动管理事务:

tx := db.Begin()
defer tx.Rollback()

后来发现GORM提供了更优雅的方式:

db.Transaction(func(tx *gorm.DB) error { ... })
  1. 遇到的坑
  • 依赖管理:go.mod的版本冲突真是让人头疼
  • 并发问题:库存扣减时的并发控制差点就漏掉了
  • 密码加密:差点把明文密码存到数据库(这可太危险了)

如何运行项目

  1. 环境准备:
  • Go 1.18+
  • MySQL 8.0
  • 创建数据库:'CREATE DATABASE myshop;'
  1. 获取代码: 'git clone [项目地址] cd myshop'
  2. 安装依赖: 'go mod tidy'
  3. 修改配置: 主要是数据库连接信息,在 main.go 中: 'root:123456@tcp(localhost:3306)/myshop'
  4. 运行项目: 'go run cmd/main.go'

测试流程

我写了一个PowerShell测试脚本(test.ps1),包含了主要功能的测试:

  1. 用户注册: 'Invoke-RestMethod -Method Post -Uri "http://localhost:8080/api/user/register" ...'
  2. 用户登录: 'Invoke-RestMethod -Method Post -Uri "http://localhost:8080/api/user/login" ...'
  3. 创建商品: 'Invoke-RestMethod -Method Post -Uri "http://localhost:8080/api/products" ...'
  4. 创建订单: 'Invoke-RestMethod -Method Post -Uri "http://localhost:8080/api/orders" ...'

未来计划

说实话,这个项目还有很多可以改进的地方:

  1. 性能优化
  • 添加缓存
  • 优化数据库查询
  • 使用连接池
  1. 功能完善
  • 支付功能
  • 订单状态机
  • 商品分类
  • 购物车
  1. 工程优化
  • 配置文件
  • 日志系统
  • 监控告警
  • CI/CD

个人感悟

从Java转Go的过程中,最大的感受是:

  1. Go的简洁真的很吸引人,没有Java那么多的设计模式和框架
  2. 错误处理虽然繁琐,但确实让代码更可靠
  3. 并发编程比Java简单,但也更容易出错
  4. 依赖管理比Maven简单多了

这个项目教会我的最重要的一点是:先把基础打好,再考虑高级功能。有时候,简单反而是最好的解决方案。

如果你也想尝试这个项目,欢迎交流!

从Java到Go的转变历程

说实话,最开始写Go的时候,总是不自觉地用Java的思维方式。比如:

  1. 想要用接口定义所有东西(Java的习惯)
  2. 喜欢写很长的类名(UserServiceImplementation)
  3. 习惯性地想加入设计模式(工厂、构建者、单例...)
  4. 想把所有东西都封装起来

但随着深入学习,我逐渐理解了Go的哲学:

  1. 简单胜于复杂

    • Go代码就应该简单直接
    • 不需要过度封装
    • 显式优于隐式
    • 实用主义至上
  2. 组合优于继承

    • Go没有继承,这是刻意的设计
    • 用组合实现代码复用更灵活
    • 扁平的结构比深层继承更好维护
    • 接口应该小而精
  3. 显式错误处理

    • 一开始觉得if err != nil很烦
    • 后来发现这让代码更可靠
    • 错误处理不应该被隐藏
    • 迫使你思考每个错误场景

对Go语言的新认识

  1. 并发模型

    • goroutine真的很轻量
    • channel的设计很优雅
    • CSP模型比共享内存更安全
    • 但也要小心goroutine泄漏
  2. 依赖管理

    • go mod比Maven简单太多
    • 版本管理更直观
    • vendor机制很实用
    • 依赖分析工具很强大
  3. 标准库

    • 标准库设计很优秀
    • 接口定义简洁明了
    • io包的设计特别棒
    • context的使用很优雅

工程实践的心得

  1. 关于项目结构

    • 不要过度分层
    • 保持依赖关系清晰
    • 适度封装,不要过度
    • 文件组织要有意义
  2. 关于代码风格

    • 追求简洁,不要炫技
    • 命名要有意义但不要太长
    • 注释要解释为什么,而不是是什么
    • 保持一致性很重要
  3. 关于测试

    • 表格驱动测试很实用
    • 基准测试要经常做
    • 测试要关注边界条件
    • mock要适度使用

对后端开发的思考

  1. 技术选择

    • 不要盲目追求新技术
    • 选择要基于实际需求
    • 可维护性比性能更重要
    • 团队熟悉度要考虑
  2. 架构设计

    • 先做简单的实现
    • 在需要时再优化
    • 过度设计是万恶之源
    • 可扩展性要适度
  3. 性能优化

    • 先有监控和数据
    • 再定位具体问题
    • 然后针对性优化
    • 最后验证效果

职业发展的思考

  1. 技术广度和深度

    • 掌握多种语言很有帮助
    • 但要有一门精通的
    • 底层原理要懂
    • 工程实践很重要
  2. 学习方法

    • 多写代码
    • 读优秀源码
    • 参与开源项目
    • 记录和分享
  3. 成长路径

    • 打好基础很重要
    • 实践经验必不可少
    • 持续学习的习惯
    • 培养工程思维

给新手的建议

  1. 学习建议

    • 先理解Go的设计哲学
    • 不要带着其他语言的思维
    • 多看官方文档
    • 多写小项目练手
  2. 开发建议

    • 从简单的需求开始
    • 先实现再优化
    • 重视代码质量
    • 保持好的编码习惯
  3. 进阶建议

    • 研究优秀开源项目
    • 参与社区讨论
    • 写技术博客
    • 坚持动手实践

未来的学习计划

  1. 技术方向

    • 深入学习Go底层原理
    • 研究并发编程模式
    • 学习分布式系统
    • 微服务架构实践
  2. 项目计划

    • 完善当前项目
    • 尝试微服务改造
    • 加入更多工程实践
    • 写更多技术文章
  3. 长期目标

    • 参与Go开源项目
    • 构建个人技术栈
    • 分享技术经验
    • 帮助他人成长

结语

这个项目让我明白:编程不仅仅是写代码,更是一种思维方式的转变。Go语言的简洁优雅,让我重新思考了很多编程的本质问题。

最后想说:保持简单,保持好奇,保持学习的热情。技术之路没有终点,但每一步都很有趣。

希望这个项目能帮助到其他学习Go的朋友。如果你也在学习Go,欢迎交流讨论!

常见问题解答

Q: 为什么选择Gin框架? A: 简单、轻量、文档全,社区活跃。

Q: 数据库为什么用MySQL? A: 主要是考虑到大家都熟悉,容易上手。

Q: 为什么不用微服务架构? A: 目前的规模还用不着,过度设计反而会增加复杂性。

记住,这只是个开始,代码永远写不完,但要让它先能跑起来! 代码我整理好后会给仓库链接,期待更新吧。