首页 > 其他分享 >Golang中interface的使用建议

Golang中interface的使用建议

时间:2022-12-27 14:56:20浏览次数:47  
标签:建议 package 接口 Server Golang func interface type

https://medium.com/@mbinjamil/using-interfaces-in-go-the-right-way-99384bc69d39

分享的是一个关于Golang中interface的正确使用方法。

讲道理在medium上找一篇对我有所帮助的文章还挺难的,大多是比较简单的教程,或者是空谈与介绍。

Accept Interfaces, Return Structs

接口是一组对象的方法的抽象集合,所以我们在实现具体方法前,不应该先考虑如何去定义interface。我们应该在观察消费者行为的时候,抽象消费者所需要的方法,而不是在实现的时候考虑如何去抽象。

Go Code Review Comments里提到一点:

Go interfaces generally belong in the package that uses values of the interface type, not the package that implements those values.

也就是,一个接口应该出现在消费者的package里,而不是实现的package里。

Don’t Do this

package tcp

type Server interface {
    Start()
}

type server struct { ... }

func (s *server) Start() { ... }

func NewServer() Server { 
    return &server{ ... } 
}
package consumer
import “tcp”	//耦合

func StartServer(s tcp.Server) { 
    s.Start() 
}

这是非常不推荐的interface的用法,因为它不是为了抽象的目的而定义的,而且这种写法将消费者包耦合到了实施者包。

Do This Instead

package tcp
type Server struct { ... }
func (s *server) Start() { ... }
func NewServer() Server { return &Server{ ... } }
package consumer
type Server interface {
    Start() 
}
func StartServer(s Server) { s.Start() }

这样的话就把实现package跟消费package解耦了,消费者只需要关心,这个interface所拥有的方法,而不需要关心其他。

Go Standard Library

这部分主要是提及在golang standard中,上述原则的体现。

像在io包中

type Reader interface {
    Read(p []byte) (n int, err error)
}
func Copy(dst Writer, src Reader) (written int64, err error)

还有HTTP包中

type Handler interface { 
    ServeHTTP(ResponseWriter, *Request) 
} 
func ListenAndServe(addr string, handler Handler) error

Interface Segregation Principle

这部分是讲上述原则其实也是为了SOLID原则,即其中的 Interface Segregation Principle也就是接口隔离原则。

“Clients should not be forced to depend on interfaces that they do not use.”

同时,消费者应该只接收含有他们所关心方法的接口。

// os.File contains many unrelated methods 
func Save(f *os.File, doc *Document) error 
// io.ReadWriteCloser contains unrelated Read() and Close() methods 
func Save(rwc io.ReadWriteCloser, doc *Document) error
// io.Writer contains only one method Write() that is required 
func Save(w io.Writer, doc *Document) error

第一个方法,os.File包含了太多用户不需要的函数、

第二个方法,io.ReadWriteCloser包含了与定义不相关的Read()和CLose()

第三个方法,正好是我们所需要的。

当我们在使用它们之前定义接口时,即在生产者包中,它们通常是包含许多方法的大型接口。此外,这些接口将添加新方法,因为实现会随着时间而变化。这意味着使用相同接口的所有消费者更有可能拥有与其功能无关的方法。

因此,仅在需要使用接口时才定义接口意味着我们遵循接口隔离原则。并且通过遵循这个原则,我们可以防止为多个职责定义方法的臃肿接口,从而产生更易于维护的 Go 代码

标签:建议,package,接口,Server,Golang,func,interface,type
From: https://www.cnblogs.com/Vikyanite/p/17008066.html

相关文章

  • Golang开发项目目录简介以及目录结构设置规范
    一、Golang项目简单介绍Golang简单的目录结构如下:其中,bin用来存放经过gobulid后的可执行文件,pkg存放编译后的gomodule,而src就存放我们项目的代码 二、三种常用目录结......
  • Golang 环境变量和项目结构
    1.Golang环境变量和项目结构常用exportGO_HOME=/opt/modules/goexportGOPATH=/home/user/go$GO_HOME/bin:$GOPATH/bin12341.1.为什么我使用gobuild命令没有没有......
  • Golang一角:环境变量(Go开发必需的环境变量、普通环境变量)
    “环境变量”这个词,有经验的开发同学对它一定很熟悉了,它提供给软件工程以高灵活性、高扩展性,大到操作系统,小到某个项目,都有它的影子,它的表现方式有很多。微服务应用提倡将......
  • Golang 项目使用 Gitlab CI/CD 自动化持续集成
    GitlabCI/CD自动化持续集成该功能主要是代码提交到gitlab后,gitlab能按照指定的脚本,去运行诸如测试、构建、发布自动化,避免手工操作本文将演示以下集成项目: 测试(T......
  • golang项目代码push到gogs上,如何自动编译、打镜像、k8s上运行?
    golang项目代码push到gogs上,如何自动编译、打镜像、k8s上运行? 上面的环境,都需要搭建。测试demo见git地址主要是test1/.drone.yml的编写。from_secret:kube_toke......
  • Golang项目在idea中运行遇到的坑
    因为是第一次搞go的项目,也没有学过go这个语言,凭借着强大的运气开始修改开源项目wayne的源码。运行过程中,遇到了好多问题。第一个问题就是后端的go项目没法启动。1.数据......
  • 【Golang 快速入门】项目实战:即时通信系统
    即时通信系统-服务端项目架构图: 版本迭代:版本一:构建基础Server版本二:用户上线功能版本三:用户消息广播机制版本四:用户业务层封装版本五:在线用户查询版本六:修改用户名......
  • golang入门项目—日志收集
    传统ELK架构的日志收集:存在的问题:Logstash耗资源较大,运行占用CPU和内存高。另外没有消息队列缓存,存在数据丢失隐患。适用于小规模的集群使用。第二种架构:位于各个节点上......
  • Golang 项目部署
    Go语言项目部署,Go项目部署注:本教程不包含golang编译部分,请自行编译;项目使用supervisor进行部署。supervisor详细操作可以参考:Supervisor配置详解问题可以参考:error:......
  • Docker一键部署Golang项目
    Docker部署go项目首先我们把我们写的go项目通过Xftp传到服务器上面,或者通过git从Coding里面拉取一份,未来方便起见我是把我的所有的go项目都放在了/usr/local/goproject目......