面向对象编程三大特点:封装、继承、多态。

1. 构造函数

Go不支持构造器。如果某类型的零值不可用,需要提供NewT(parameters)函数,用来初始化T类型的变量。按照Go的惯例,应该把创建T类型变量的函数命名为NewT(parameters),若一个包中只含有一种类型,则函数名为New(parameters)。

包含NewT()函数的包的结构体应该首字母小写,以使结构体对外不可引用,只能通过NewT()创建结构体。相应的,结构体内所有字段也应该小写,被隐藏,方法要根据实际情况确认。

// oop/employee/employee.go
package employee
import "fmt" type employee struct {
firstName string
lastName string
totalLeaves int
leavesTaken int
} func New(firstName string, lastName string, totalLeaves int, leavesTaken int) employee{
e := employee{firstName, lastName, totalLeaves, leavesTaken}
return e
} func (e employee) LeavesRemaining(){
fmt.Printf("%s %s has %d leaves remaining", e.firstName, e.lastName, e.totalLeaves-e.leavesTaken)
} //oop/main.go
package main
import "oop/employee" func main(){
/*
e := employee.Employee{
FirstName: "wang",
LastName: "qing",
TotalLeaves: 30,
LeavesTaken: 20,
}
*/
e := employee.New("wang", "qing", , )
e.LeavesRemaining()
}

2. 继承

Go不支持继承,但他支持组合(composition)。组合的一般含义定义为“合并在一起”。

一般通过嵌套结构体进行组合。

3. 多态

Go通过接口来实现多态。在Go中,一个类型如果定义了接口所声明的全部方法,那该类型就实现了该接口。

所有实现了接口的类型,都可以把它的值保存在一个接口类型的变量中。在 Go 中,我们使用接口的这种特性来实现多态

4.面向接口

golang中面向对象编程更多的体现为面向接口。

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

它为我们的程序提供了非常强的灵活性,想要构建一个稳定、健壮的 Go 语言项目,不使用接口是完全无法做到的。

单元测试是一个项目保证工程质量最有效并且投资回报率最高的方法之一,作为静态语言的 Go,想要写出覆盖率足够(最少覆盖核心逻辑)的单元测试本身就比较困难,因为我们不能像动态语言一样随意修改函数和方法的行为,而接口就成了我们的救命稻草,写出抽象良好的接口并通过接口隔离依赖能够帮助我们有效地提升项目的质量和可测试性。

如下代码其实就不是一个设计良好的代码,它不仅在 init 函数中隐式地初始化了 grpc 连接这种全局变量,而且没有将 ListPosts 通过接口的方式暴露出去,这会让依赖 ListPosts 的上层模块难以测试。

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
}
  1. 通过接口 Service 暴露对外的 ListPosts 方法;
  2. 使用 NewService 函数初始化 Service 接口的实现并通过私有的结构体 service 持有 grpc 连接;
  3. ListPosts 不再依赖全局变量,而是依赖接口体 service 持有的连接;

当我们使用这种方式重构代码之后,就可以在 main 函数中显式的初始化 grpc 连接、创建 Service 接口的实现并调用 ListPosts 方法:

package main

import ...

func main() {
conn, err = grpc.Dial(...)
if err != nil {
panic(err)
} svc := post.NewService(conn)
posts, err := svc.ListPosts()
if err != nil {
panic(err)
} fmt.Println(posts)
}

这种使用接口组织代码的方式在 Go 语言中非常常见,我们应该在代码中尽可能地使用这种思想和模式对外提供功能:

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

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

参考:

1.Go 系列教程(Golang tutorial series) go语言中文网

2. 如何写出优雅的 Go 语言代码

golang面向对象实现的更多相关文章

  1. golang面向对象和interface接口

    一. golang面向对象介绍 1.golang也支持面向对象编程,但是和传统的面向对象编程有区别,并不是纯粹的面向对象语言.2.golang没有类(class),golang语言的结合体(struc ...

  2. Golang面向对象编程-struct(结构体)

    Golang面向对象编程-struct(结构体) 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.什么是面向对象编程 面向对象编程(Object Oriented Program ...

  3. golang 面向对象编程

    概述 Golang语言的面向对象与c++,py等语言有所不同,是由于Golang不支持继承:与上述支持聚合和继承的面向对象的语言不同,Golang只支持聚合(也叫做组合)和嵌入.聚合和嵌入的区别: t ...

  4. 【GoLang】golang 面向对象编程 & 面向接口编程

    005.面向对象&接口编程 1 面向函数编程 1.1 将数据作为参数传递到函数入参 1.2 对象与函数是分离的 2 面向对象编程 2.1 使用者看起来函数作为对象的属性而非参数 2.2 函数属 ...

  5. golang面向对象分析

    说道面向对象(OOP)编程, 就不得不提到下面几个概念: 抽象 封装 继承 多态 其实有个问题Is Go An Object Oriented Language?, 随便谷歌了一下, 你就发现讨论这个 ...

  6. golang面向对象初识

    struct是变量的集合 interface是方法的集合 struct与interface都支持匿名字段, 换言之, 支持组合实现继承. golang的struct与C++的class一样, 只能声明 ...

  7. golang 面向对象

    深入理解GO语言的面向对象_Golang_脚本之家 https://www.jb51.net/article/94030.htm 深入理解GO语言的面向对象 更新时间:2016年10月04日 10:4 ...

  8. Golang面向对象_继承

    package main import "fmt" type Person struct { name string //名字 sex byte //性别 age int //年龄 ...

  9. Golang 中的 面向对象: 方法, 类, 方法继承, 接口, 多态的简单描述与实现

    前言: Golang 相似与C语言, 基础语法与C基本一致,除了广受争议的 左花括号 必须与代码同行的问题, 别的基本差不多; 学会了C, 基本上万变不离其宗, 现在的高级语言身上都能看到C的影子; ...

随机推荐

  1. Delphi根据不同分隔符获取字符串内容

    function GetFieldValue(separator:Char;strLine: string; nNum: Integer): string; var Strs :TStrings; R ...

  2. windows安装boost

    2019年11月4日16:00:36 Boost.Asio 使用文档 https://mmoaay.gitbooks.io/boost-asio-cpp-network-programming-chi ...

  3. ASP.Net validator

    <asp:TextBox ID="txtTransitDays" runat="server"></asp:TextBox> <a ...

  4. 华为交换机trunk端口更改access提示:Error: Please renew the default configurations.

    现象: 华为交换机接口由原来 trunk 接口更改 access 提示 Error: Please renew the default configurations. 解决方法: 在交换机视图模式下, ...

  5. 选redis还是memcache,源码怎么说

    转自: https://mp.weixin.qq.com/s?__biz=MjM5ODYxMDA5OQ==&mid=2651961272&idx=1&sn=79ad515b01 ...

  6. [转帖]NSA武器库知识整理

    NSA武器库知识整理 https://www.cnblogs.com/FrostDeng/p/7120812.html 美国国家安全局(NSA)旗下的“方程式黑客组织”(shadow brokers) ...

  7. ACM算法锦集

    一:知识点 数据结构: 1,单,双链表及循环链表 2,树的表示与存储,二叉树(概念,遍历)二叉树的 应用(二叉排序树,判定树,博弈树,解答树等) 3,文件操作(从文本文件中读入数据并输出到文本文 件中 ...

  8. Python之虚拟环境virtualenv、pipreqs生成项目依赖第三方包

    virtualenv简介 含义: virtual:虚拟,env:environment环境的简写,所以virtualenv就是虚拟环境,顾名思义,就是虚拟出来的一个新环境,比如我们使用的虚拟机.doc ...

  9. DISPLAY FORMAT 語法

  10. vuex的Store简单使用过程

    介绍 Store的代码结构一般由State.Getters.Mutation.Actions这四种组成,也可以理解Store是一个容器,Store里面的状态与单纯的全局变量是不一样的,无法直接改变st ...