如何写出优雅的go代码

今天又看到一篇很不错的文章:
https://mp.weixin.qq.com/s/yiU18PzHDxeCXc5YR5x9Ow

感觉比较有用的建议
1 目录结构

├── LICENSE.md
├── Makefile
├── README.md
├── api
├── assets
├── build
├── cmd
├── configs
├── deployments
├── docs
├── examples
├── githooks
├── init
├── internal
├── pkg
├── scripts
├── test
├── third_party
├── tools
├── vendor
├── web
└── website

具体说明在:readme

2 模块拆分
这一部分就是之前常常学习、实践但一直不知道怎么称呼他的MVC结构。这是一种 Web 框架的最常见架构方式,将服务中的不同组件分成了 Model、View 和 Controller 三层。
但go语言开发者的理解其实并不是这样的,go里面更喜欢按功能职责拆分,主要原因:

Go 语言项目中的每一个文件目录都代表着一个独立的命名空间,也就是一个单独的包,当我们想要引用其他文件夹的目录时,首先需要使用 import 关键字引入相应的文件目录,再通过 pkg.xxx 的形式引用其他目录定义的结构体、函数或者常量,如果我们在 Go 语言中使用 model、view 和 controller 来划分层级,你会在其他的模块中看到非常多的 model.Post、model.Comment 和 view.PostView。

3 注意显示隐式,比如init 和 error的处理
4 接口的意义:面向接口编程。

为不同层级的模块提供了一个定义好的中间层,上游不再需要依赖下游的具体实现,充分地对上下游进行了解耦。

对比两段代码:

package post

var client *grpc.ClientConn

func init() {
    var err error
    client, err = grpc.Dial(...if err != nil {
        panic(err)
    }
}

func ListPosts() ([]*Post, error) {
    posts, err := client.ListPosts(...)
    if err != nil {
        return []*Post{}, err
    }
    
    return posts, nil
}

//---------------------------------

package post

type Service interface {
    ListPosts() ([]*Post, error)
}

type service struct {
    conn *grpc.ClientConn
}

func NewService(conn *grpc.ClientConn) Service {
    return &service{
        conn: conn,
    }
}

func (s *service) ListPosts() ([]*Post, error) {
    posts, err := s.conn.ListPosts(...)
    if err != nil {
        return []*Post{}, err
    }
    
    return posts, nil
}

使用大写的 Service 对外暴露方法;
使用小写的 service 实现接口中定义的方法;
通过 NewService 函数初始化 Service 接口;

当我们使用上述方法组织代码之后,其实就对不同模块的依赖进行了解耦,也正遵循了软件设计中经常被提到的一句话 — 『依赖接口,不要依赖实现』,也就是面向接口编程。

如果你不知道应不应该使用接口对外提供服务,这时就应该无脑地使用上述模式对外暴露方法了,这种模式可以在绝大多数的场景下工作,至少作者到目前还没有见到过不适用的。

5 单元测试
单元测试就是业务逻辑。 应该尽可能的覆盖自己的业务逻辑。

6 函数简单

另一个建议就是保证每一个函数尽可能简单,这里的简单不止是指功能上的简单、单一,还意味着函数容易理解并且命名能够自解释。

这个确实,但要做到的话还挺难的。

7 测试时候的mock 和 断言

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值