引用外部资源最好自己封装一层


写在前面

在公司开发业务过程中发现经常需要引用外部资源,包括外部服务rpc、http、rocketmq,还有外部依赖包log、error、common等,在代码各个模块、各个文件里面直接引用,这有什么问题呢?

  • 需要替换某个包的时候需要修改所有引用的地方。之前在项目中引用excelize包的时候发现有个bug,因此需要替换这个包,发现需要改很多文件。
  • 不知道外部依赖能提供哪些接口。如果直接在需要用rpc的地方直接使用client,需要引入相关的requst和response的定义,并且根本不摘除client提供了哪些方法,需要查看proto。最坑的是如果client修改了某个接口的定义,所有调用的地方都需要修改,包括单测。这个改动可能仅仅是某个场景需要而加的,但是导致其他所有场景都需要改这个接口,显然不合理。
  • 业务代码到处引入外部依赖包。
  • 当需要对某个接口做统一处理的时候无法实现。比如想对某个rpc调用统计耗时,需要在每个调用的地方加上相关代码,太恶心。

解决方法:将外部资源封装一层

将当前服务引入的外部资源放在一个目录下,并且通过定义好接口,封装一层

pkg
├── error
│   └── error.go
├── excel
│   └── excel.go
├── rocketmq
│   └── rocketmq.go
└── rpc
    ├── service1.go
    └── service2.go

error/error.go文件如下:

package error

import (
	"github.com/pkg/errors"
)

type Error interface {
	Errorf(format string, args ...interface{}) error
	Wrapf(err error, format string, args ...interface{}) error
}

func New() Error {
	return &innerError{}
}

type innerError struct {
	// err error
}

func (i *innerError) Errorf(format string, args ...interface{}) error {
	// TODO:可以做一些本服务相关的事情,比如报警、保存、添加服务、用户相关信息到error中
	return errors.Errorf(format, args...)
}

func (i *innerError) Wrapf(err error, format string, args ...interface{}) error {
	return errors.Wrapf(err, format, args...)
}

在其他业务文件中只要引入pkg/error包就行了,无需关心github.com/pkg/errors

总结

本文纯属个人观点和习惯,肯定有人会觉得多此一举,因为在代码review的时候就有同事提出来没有必要,觉得直接在用到的地方直接引用github.com/pkg/errors就行了。有不同意见可留言探讨,一起学习。

每天学习一个知识点,必定会有质变!


文章作者: Alex
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Alex !
  目录