Golang:微服务常用代码分层结构

1.代码结构

代码分层结构是一个老生常谈的话题,好的代码结构能够使得系统易于理解、开发及维护,如果代码结构很混乱就会使得不同层级的代码块耦合,导致难以维护和拓展。
比较经典的代码结构(宏观)有Web的MVC模式分层结构,将代码分为Controller路由层、Model模型层、View视图层。
在这里插入图片描述

更加具体地来看,对于微服务来说(不考虑前后端一体化情况),后端只有Controller及Model层, 可以细化为:

  • controller层:路由层,定义接口的路由
  • service层:逻辑层,定义服务的逻辑
  • dao层:数据层,定义数据库间的交互
  • entity层:实体层,定义数据PO、DTO、VO等结构
  • utils层:工具层,定义各类工具
    在这里插入图片描述

2.Golang:微服务代码分层结构

这里分享一下工作中常用到的Golang微服务代码分层结构,以及每一层结构的定义及能做的事情、不能做的事情。
在这里插入图片描述

由于Golang是不支持包之间循环依赖的,所以从hanlders到pkgs,均为单向依赖。下面介绍各个层级的含义,以及要做的事情。

2.1.pkg

pkg包存放与业务逻辑无关的工具包,如格式化工具、结构体转换工具等。

pkg/
 |- formatter/
  |- formatter.go
 |- converter/
  |- converter.go
  • converter.go
func obj2String(obj interface{}) (string, error) {
    bytes, err := json.Marshal(&obj)
    if err != nil {
        return "", err
    }
    return string(bytes), nil
}

2.2.entity

entity包存放领域实体及其相关方法及枚举。

  • entity包只能提供最基本的和实体相关的方法,如定义了User结构体,提供IsValidUser方法判断该User是否有效等。
  • entity包不依赖于其他任何包(基础类库、pkgs包)除外,只提供最基础的领域模型定义。
entity/
 |- user.go
 |- item.go
  • user.go
type UserType string

const (
    UserTypeAdmin  UserType = "admin"
    UserTypeNormal UserType = "normal"
)

type User struct {
    UserType UserType
    UserID   int64
    UserName string
}

func (u *User) IsAdmin() bool {
    return u.UserType == UserTypeAdmin
}

2.3.dao

dao包存放于数据库交互的所有代码,即数据的增、删、改、查。

  • dao包包含领域模型的所有数据CRUD操作
  • dao包不包含业务逻辑相关的操作
dao/
 |- dao.go
 |- user_dao.go
  • dao.go
var UserDao UserDaoIF

func InitDAO() {
    UserDao = new(userDao)
}
  • user_dao.go
type UserDaoIF interface {
    GetUser(userID int64) (*entity.User, error)
    CreateUser(user *entity.User) error
}

type userDao struct{}

// CreateUser implements UserDaoIF
func (*userDao) CreateUser(user *entity.User) error {
    panic("unimplemented")
}

// GetUser implements UserDaoIF
func (*userDao) GetUser(userID int64) (*entity.User, error) {
    panic("unimplemented")
}

2.4.policies

policies包存放和业务逻辑校验、实体验证相关的代码。

policies/
 |- policy.go
 |- user_policy.go
  • policy.go
var UserPolicy UserPolicyIF

func Init() {
    UserPolicy = new(userPolicy)
}
- user_policy.go
type UserPolicyIF interface {
    CanLogin(userID int64) bool
    CanRegister(userID int64) bool
}

type userPolicy struct{}

// CanLogin implements UserPolicyIF
func (*userPolicy) CanLogin(userID int64) bool {
    panic("unimplemented")
}

// CanRegister implements UserPolicyIF
func (*userPolicy) CanRegister(userID int64) bool {
    panic("unimplemented")
}

2.5.services

services存放业务逻辑相关代码,是整个项目中逻辑最复杂的部分。

services/
 |- service.go
 |- user/
  |- user_service.go    
 |- item/
  |- item_service.go
  • service.go
var UserService UserServiceIF

func Init() {
    UserService = new(userService)
}
- user_service.go
type UserServiceIF interface {
    UserLogin(u *entity.User) error
}

type userService struct{}

// UserLogin implements UserServiceIF
func (*userService) UserLogin(u *entity.User) error {
    panic("unimplemented")
}

2.6.handlers

handlers定义了各类对外处理器入口,如http、rpc、eventbus等处理器。

  • handlers中的处理器只做三件事情:接受请求解析入参、调用services完成业务逻辑、构造响应参数
  • handlers不包含业务代码逻辑,应该简单地作路由使用
handlers/
 |- handler.go
 |- rpc/
  |- user_rpc.go    
 |- http/
  |- item_http.go

2.7.其他包

  • conf包:存放相关的配置文件,如config_prod.yaml等
  • script包:存放系统相关的脚本,如编译脚本build.sh等
  • cmd包:存放相关的可直接运行的go脚本,如刷数脚本reflush.go等

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/101044.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Spring Cloud Foundry上使用通配符模式匹配进行的安全绕过漏洞 CVE-2023-20873

文章目录 0.前言1.参考文档2.基础介绍描述如果满足以下任一条件,应用程序就不会有太大风险:受影响的Spring产品和版本 3.解决方案3.1. 升级版本3.2. 替代方案 0.前言 背景:公司项目扫描到 Spring Cloud Foundry上使用通配符模式匹配进行的安全…

tp5使用redis及redis7.2安装到window系统上面

redis安装教程 redis7.2安装到window系统上面 https://download.csdn.net/download/qq_39161501/88269037 解决方案:修改配置php.ini文件 打开Apache目录下的php.ini文件,搜索extension,在空白处加上下列代码: 注:e…

2019CVPR Semantic Graph Convolutional Networks for 3D Human Pose Regression

基于语义图卷积网络的三维人体姿态回归 源码 https://github.com/garyzhao/SemGCN 摘要 在本文中,我们研究了学习图卷积网络(GCN)回归的问题。GCN的当前体系结构受限于卷积滤波器和共享的变换矩阵为的小感受野。为了解决这些限制&#xff…

并发 04(Callable,CountDownLatch)详细讲解

并发 Callable 1 可以返回值 2可以抛出异常 泛型指的是返回值的类型 public class Send {public static void main(String[] args) {//怎么启动Callable//new Thread().start();Aaa threadnew Aaa();FutureTask futureTasknew FutureTask(thread);new Thread(futureTask,&qu…

划分字母区间【贪心算法】

划分字母区间 给你一个字符串 s 。我们要把这个字符串划分为尽可能多的片段,同一字母最多出现在一个片段中。 注意,划分结果需要满足:将所有划分结果按顺序连接,得到的字符串仍然是 s 。返回一个表示每个字符串片段的长度的列表。…

深度学习6:自然语言处理-Natural language processing | NLP

目录 NLP 为什么重要? 什么是自然语言处理 – NLP NLP 的2大核心任务 自然语言理解 – NLU|NLI 自然语言生成 – NLG NLP(自然语言处理) 的5个难点 NLP 的4个典型应用 NLP 的 2 种途径、3 个核心步骤 总结 自然语言处理 NLP 为什么重要? “语言…

Unity3D下如何采集camera场景数据并推送RTMP服务?

Unity3D使用场景 Unity3D是非常流行的游戏开发引擎,可以创建各种类型的3D和2D游戏或其他互动应用程序。常见使用场景如下: 游戏开发:Unity3D是一个广泛用于游戏开发的环境,适用于创建各种类型的游戏,包括动作游戏、角…

汽车电子笔记之:基于AUTOSAR的多核监控机制

目录 1、概述 2、系统监控的目标 2.1、任务的状态机 2.2、任务服务函数 2.3、任务周期性事件 2.4、时间监控的指标 2.5、时间监控的原理 2.6、CPU负载率监控原理 2.6.1、设计思路 2.6.2、监控方法的评价 3、基于WDGM模块热舞时序监控方法 3.1、活跃监督 3.2、截至时…

wireshark 流量抓包例题

一、题目一(1.pcap) 题目要求: 1.黑客攻击的第一个受害主机的网卡IP地址 2.黑客对URL的哪一个参数实施了SQL注入 3.第一个受害主机网站数据库的表前缀(加上下划线例如abc) 4.第一个受害主机网站数据库的名字 看到题目SQL注入&#xff0c…

Modbus通信协议

Modbus通信协议 一、概述 Modbus通信协议是一种工业现场总线协议标准,常用的Modbus协议有以下三种类型:Modbus TCP、Modbus RTU、Modbus ASCll。 Modbus通信协议解决了通过串行线路在电子设备之间发送信息的问题。该协议在遵循该协议的体系结构中实现主…

CSAPP的Lab学习——BombLab

文章目录 前言一、一号炸弹(小试牛刀)二、二号炸弹(六重循环)三、三号炸弹(不同输入,不同答案)四、四号炸弹(判断语句的实现)五、五号炸弹(跳转,循…

【MTK平台】根据kernel log分析wifi scan的时候流程

一 概要: 本文主要讲解根据kernel log分析下 当前路径下(vendor/mediatek/kernel_modules/connectivity/wlan/core/gen4m/)wifi scan的时候代码流程 二. Log分析: 先看Log: 2.1)在Framework层WifiManager.java 方法中,做了一个标记,可以精准的确认时间 这段log可以…

探索UniApp分包

目录 什么是UniApp分包? UniApp分包的原理 优势 如何使用UniApp分包 1.manifest.json文件配置 2.静态图片资源分包注意事项 3.pages.json配置 结论 探索UniApp分包:优化移动应用性能与用户体验 在移动应用开发领域,性能和用户体验是至…

【vue2第七章】vue的四个生命周期与八个钩子函数

vue的四个生命周期与八个钩子函数 Vue的四个生命周期有:创建(creation)、挂载(mounting)、更新(updating)和销毁(destroying)。 钩子函数是什么: vue生命周…

vue3下的密码输入框(antdesignvue)

参考:vue下的密码输入框 注意:这是个半成品,有些问题(input输入框加了文字间距letter-spaceing,会导致输入到第6位的时候会往后窜出来一个空白框、光标位置页会在数字前面),建议不采用下面这种方式,用另外的(画六个input框更方便) 效果预览 实现思路 制作6个小的正方…

Linux中Tomcat发布war包后无法正常访问非静态资源

事故现象 在CentOS8中安装完WEB环境,首次部署WEB项目DEMO案例,发现可以静态的网页内容, 但是无法向后台发送异步请求,全部出现404问题,导致数据库数据无法渲染到界面上。 原因分析 CentOS请求中提示用来获取资源的连…

Prometheus监控(一)

文章目录 监控对于企业和运维工作的重要性监控?告警?数据采集 Prometheus介绍Prometheus相对于老牌监控的优势和不足 理想的监控系统的实现监控系统设计(架构师)监控系统的搭建数据采集的编写监控数据分析和算法稳定性测试监控自动…

IPC进程间通信及示例代码

一. 什么是进程通信 进程通信( InterProcess Communication,IPC)就是指进程之间的信息交换。实际上,进程的同步与互斥本质上也是一种进程通信(这也就是待会我们会在进程通信机制中看见信号量和 PV 操作的原因了&#x…

什么?内存爆了?详细解读虚拟内存机制

不知道大家在运行自己写的程序时,有没有发现一个问题:就是物理机器明明只有8G内存,但是我们运行的程序却可以申请到16G的内存?或者说机器上运行的多个进程,占用的总内存已经远超物理内存了,却还能正常工作。…

pdf转换成图片免费软件用哪个?pdf转换成图片就用它

随着技术的发展,现在企业办公运用到的电子文档各种各样,我们日常需要掌握的技能越来越高要求,其中pdf和图片是我们经常接触的文件格式之一,而且这两个文件格式我们会经常将它们进行转换,那么pdf转换成图片怎么操作呢?…