返回顶部
首页 > 资讯 > 后端开发 > GO >分析Go语言接口的设计原则
  • 492
分享到

分析Go语言接口的设计原则

2024-04-02 19:04:59 492人浏览 独家记忆
摘要

目录一、前言二、开闭原则三、依赖倒置原则3.1、什么是依赖倒置原则  3.2、一个耦合度极高的模块关系设计3.3、面向抽象层依赖倒转一、前言 Go的interface写起来更自由,

一、前言

Go的interface写起来更自由, 无需显示的实现, 只要实现了与interfece所包含的所有函数签名的相同的方法即可。让编码更灵活, 易扩展。

如何理解go语言中的interface呢?

1. interface是方法声明的集合

2.接口的方法与实现接口的类型方法格式一致

3.接口中所有方法均被实现

4. interface可以作为一种数据类型,实现了该接口的任何对象都可以给对应的接口类型变量赋值

特别说明两点:

  • interface 可以被任意对象实现,一个类型/对象也可以实现多个 interface
  • 方法不能重载,如eat(), eat(s string)不能同时存在

那么作为interface数据类型,他存在的意义在哪呢? 实际上是为了满足一些面向对象编程思想。我们知道,软件设计的最高目标就是高内聚,低耦合。那么其中有一个设计原则叫开闭原则。什么是开闭原则

二、开闭原则

在面向对象编程领域中,开闭原则规定“软件中的对象(类,模块,函数等等)应该对于扩展是开放的,但是对于修改是封闭的”,这意味着一个实体是允许在不改变它的源代码的前提下变更它的行为。

看重点: 对于扩展是开放的, 对于修改是封闭的.

举个例子: 银行每天要办理不同的业务, 存款, 转账, 取款等. 如果直接是实体来实现如下


package bank

import "fmt"

type Banker struct {

}

func (b *Banker) Save() {
    fmt.Println("存钱")
}

func (b *Banker) Transfer() {
    fmt.Println("转账")
}

func (b *Banker) Get() {
    fmt.Println("取钱")
}

有个人要来存钱取钱转账了


package main

import "aaa/bank"

func main() {
    var b = bank.Banker{}
    b.Save()
    b.Get()
    b.Transfer()
}

那么随着业务越来越多, 越来越大. 我又要新增加一些业务, 比如基金, 股票. 然后越来越多,越来越大. 导致Banker这个模块越来越臃肿

这样的设计会导致,当我们去给Banker添加新的业务的时候,会直接修改原有的Banker代码,那么Banker模块的功能会越来越多,出现问题的几率也就越来越大,假如此时Banker已经有99个业务了,现在我们要添加第100个业务,可能由于一次的不小心,导致之前99个业务也一起崩溃,因为所有的业务都在一个Banker类里,他们的耦合度太高,Banker的职责也不够单一,代码的维护成本随着业务的复杂正比成倍增大。

我们使用开闭原则, 使用interface将banker模块抽象出来. 然后根据这个抽象的模块, 去实现save, get, transfer.....

那么依然可以搞定程序的需求。 然后,当我们想要给Banker添加额外功能的时候,之前我们是直接修改Banker的内容,现在我们可以单独定义一个股票Banker(实现股票方法),到这个系统中。 而且股票Banker的实现成功或者失败都不会影响之前的稳定系统,他很单一,而且独立。

所以以上,当我们给一个系统添加一个功能的时候,不是通过修改代码,而是通过增添代码来完成,那么就是开闭原则的核心思想了。所以要想满足上面的要求,是一定需要interface来提供一层抽象的接口的。

golang代码实现如下:


package bank

import "fmt"

// 对银行的业务进行抽象
type Business interface {
    doBussiness()
}


// 存钱业务
type SaveBussiness struct {
}


func (b *SaveBussiness) doBussiness() {
    fmt.Sprintf("存钱")
}


//取钱业务
type GetBussiness struct {
}

func (g *GetBussiness) doBussiness() {
    fmt.Println("取钱")
}


// 转账业务
type TransferBusi struct {

}

func (t *TransferBusi) doBussiness() {
    fmt.Sprintf("转账")
}

然后我今天去了银行, 我们封装一个银行, 银行有各种各样的能力.


package main

import (
    "aaa/bank"
    "fmt"
)

// 这有一个银行, 银行可以办理业务
func Bank(b bank.Business) {
    fmt.Println("办理业务: ", b.DoBussiness())
}

func main() {
    // 办理具体的业务
    Bank(&bank.SaveBussiness{})
    Bank(&bank.GetBussiness{})
    Bank(&bank.TransferBusi{})
}

这样, 当银行增加业务类型, 比如股票的时候, 只需要扩展业务接口就可以了, 不会对原来的接口进行修改

再看开闭原则定义:开闭原则:一个软件实体如类、模块和函数应该对扩展开放,对修改关闭。简单的说就是在修改需求的时候,应该尽量通过扩展来实现变化,而不是通过修改已有代码来实现变化。

接口的意义:

现在interface已经基本了解,那么接口的意义最终在哪里呢,想必现在你已经有了一个初步的认知,实际上接口的最大的意义就是实现多态的思想,就是我们可以根据interface类型来设计api接口,那么这种API接口的适应能力不仅能适应当下所实现的全部模块,也适应未来实现的模块来进行调用。 调用未来可能就是接口的最大意义所在吧,这也是为什么架构师那么值钱,因为良好的架构师是可以针对interface设计一套框架,在未来许多年却依然适用。

三、依赖倒置原则

3.1、什么是依赖倒置原则  

依赖倒置原则(Dependence Inversion Principle)是程序要依赖于抽象接口,不要依赖于具体实现。简单的说就是要求对抽象进行编程,不要对实现进行编程,这样就降低了客户与实现模块间的耦合。

3.2、一个耦合度极高的模块关系设计

张三驾驶奔驰, 张三驾驶宝马, 张三驾驶丰田.

李四驾驶宝马, 李四驾驶奔驰, 李四驾驶丰田


package yldz

import "fmt"

// 奔驰车
type Benz struct {

}

func (b *Benz) run() string{
    return fmt.Sprintf("奔驰启动")
}
// 宝马
type BM struct {

}

func (b *BM) run() string{
    return fmt.Sprintf("宝马启动")
}
//丰田
type FT struct {

}

func (t *FT) run() string{
    return fmt.Sprintf("丰田启动")
}
//====驾车人,张三
type Zhangsan struct {

}

func (t *Zhangsan) DriverBenz(b *Benz) {
    fmt.Println("张三驾驶", b.run())
}

func (t *Zhangsan) DriverBM(b *BM) {
    fmt.Println("张三驾驶", b.run())
}

func (t *Zhangsan) DriverFT(b *FT) {
    fmt.Println("张三驾驶", b.run())
}

// 驾车人----李四.......

package main

import "aaa/yldz"

func main() {
    z := yldz.Zhangsan{}
    z.DriverBenz(&yldz.Benz{})
    z.DriverBM(&yldz.BM{})
    z.DriverFT(&yldz.FT{})
}

我们来看上面的代码和图中每个模块之间的依赖关系,实际上并没有用到任何的interface接口层的代码,显然最后我们的两个业务 张三开奔驰, 李四开宝马,程序中也都实现了。但是这种设计的问题就在于,小规模没什么问题,但是一旦程序需要扩展,比如我现在要增加一个凯迪拉克汽车 或者 司机王五, 那么模块和模块的依赖关系将成指数级递增,想蜘蛛网一样越来越难维护和捋顺。

3.3、面向抽象层依赖倒转

如上图所示,我们在设计一个系统的时候,将模块分为3个层次,抽象层、实现层、业务逻辑层。

  • 将抽象层的模块和接口定义出来,这里就需要了interface接口的设计,
  • 我们依照抽象层,依次实现每个实现层的模块,在我们写实现层代码的时候,实际上我们只需要参考对应的抽象层实现就好了,实现每个模块,也和其他的实现的模块没有关系,这样也符合了上面介绍的开闭原则。这样实现起来每个模块只依赖对象的接口,而和其他模块没关系,依赖关系单一。系统容易扩展和维护。
  • 业务逻辑层也是一样,只需要参考抽象层的接口来实现业务就好了,抽象层暴露出来的接口就是我们业务层可以使用的方法,然后可以通过多态的方向,接口指针指向哪个实现模块,调用了就是具体的实现方法,这样我们业务逻辑层也是依赖抽象成编程。

看看具体的实现


package yldz

import "fmt"

type Car interface {
    Run() string
}

type Driver interface {
    // 接口变量肚子里有一个指针, 所以接口变量不需要使用指针.
    Driver(car Car)
}


// 奔驰车
type Benz struct {

}

func (b *Benz) Run() string{
    return fmt.Sprintf("奔驰启动")
}

// 宝马车
type BM struct {

}

func (b *BM) Run() string{
    return fmt.Sprintf("宝马启动")
}

// 丰田车
type FT struct {

}

func (t *FT) Run() string{
    return fmt.Sprintf("丰田启动")
}

// ====张三
type Zhangsan struct {

}

func (t *Zhangsan) Driver(car Car) {
    fmt.Println("驾驶",car.Run())
}

func main() {

    benz := yldz.Benz{}
    zs := yldz.Zhangsan{}
    zs.Driver(&benz)

    ft := yldz.FT{}
    zs.Driver(&ft)
}

以上就是分析Go语言接口的设计原则的详细内容,更多关于Go 接口的资料请关注编程网其它相关文章!

您可能感兴趣的文档:

--结束END--

本文标题: 分析Go语言接口的设计原则

本文链接: https://lsjlt.com/news/128941.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • 分析Go语言接口的设计原则
    目录一、前言二、开闭原则三、依赖倒置原则3.1、什么是依赖倒置原则  3.2、一个耦合度极高的模块关系设计3.3、面向抽象层依赖倒转一、前言 go的interface写起来更自由, ...
    99+
    2024-04-02
  • 设计RESTful API的原则在Go语言中
    随着互联网应用的快速发展,RESTful API已经成为了许多web应用的核心设计,而Go语言作为一门快速高效的编程语言,也逐渐成为了开发RESTful API的首选语言。在Go语言中,RESTful API...
    99+
    2024-01-22
    Go语言 RESTful API 设计原则
  • Go 语言开发者必知的 HTTP API 设计原则
    Go 语言作为一种快速、高效的编程语言,已经成为了很多开发者的选择。而在实际开发中,我们常常会涉及到 HTTP API 的设计和开发。本文将分享一些 ,帮助开发者更好地设计和开发高效、可靠的 HTTP API。 1. RESTful 设计原...
    99+
    2023-07-23
    http api leetcode
  • CSS设计原则的示例分析
    今天就跟大家聊聊有关CSS设计原则的示例分析,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。相信大多数人都有过关于CSS的痛苦经历,从我加入公司到现在...
    99+
    2024-04-02
  • Go语言与C语言的设计哲学对比分析
    Go语言与C语言都是广泛使用的编程语言,各自有着不同的设计哲学和特点。本文将对这两种语言的设计哲学进行对比分析,并通过具体的代码示例来展示它们之间的区别。 1. 发展背景 C语言作为一...
    99+
    2024-03-11
    go语言 c语言 设计哲学 格式化输出
  • 如何在GO语言中优化接口设计?
    Go是一种高效且易于使用的编程语言,它的优势在于其简单的语法和强大的并发特性。在设计接口时,Go语言提供了一些有用的工具和技巧,可以帮助我们创建出高效且易于维护的接口。 下面是一些关于如何在Go语言中优化接口设计的建议: 使用接口而不是...
    99+
    2023-06-15
    自然语言处理 打包 接口
  • 分析Go语言标志的设计与意义
    Go语言标志的设计与意义 Go语言是由Google开发的一种静态、编译型的编程语言,自问世以来受到了广泛的关注和应用。作为一门新兴的编程语言,Go语言的设计在很多方面都颇具创新性,其中...
    99+
    2024-04-02
  • C#实现六大设计原则之接口隔离原则
    接口隔离原则(ISP)定义: 客户端不应该依赖它不需要的接口;一个类对另一个类的依赖应该建立在最小的接口上。 问题由来: 类A通过接口I依赖类B,类C通过接口I依赖类D,如果接口I对...
    99+
    2024-04-02
  • C#面向对象设计原则之接口隔离原则
    接口隔离原则(ISP) 定义:使用多个专门的接口比使用单一的总接口要好。即不要把鸡蛋都放到一个篮子里。好处:比较灵活、方便,不想实现的或不用实现的可以不实现。解释说明:大部分人都喜欢...
    99+
    2024-04-02
  • 容器编排中的Go语言接口设计指南
    随着云计算的发展,容器技术成为了当下热门的技术之一。容器编排技术则是容器应用的管理和部署的重要手段。在容器编排中,Go语言作为一种高效、简洁的编程语言,越来越受到开发者的青睐。本文将介绍在容器编排中,Go语言接口设计的一些指南。 接口设...
    99+
    2023-09-29
    接口 容器 函数
  • Go语言编程中分布式文件系统的设计原则是什么?
    随着互联网的快速发展,越来越多的企业和个人开始关注分布式系统的设计与实现。而分布式文件系统作为分布式系统中重要的组成部分,其设计原则也越来越受到人们的关注。 Go语言作为一门现代的高性能编程语言,越来越多的人开始使用Go语言来实现分布式文...
    99+
    2023-08-02
    编程算法 文件 分布式
  • php接口设计的基本原则是什么
    本篇内容主要讲解“php接口设计的基本原则是什么”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“php接口设计的基本原则是什么”吧!PHP接口设计是指在PHP编程实践中,设计出一种可供其他程序或系...
    99+
    2023-07-05
  • Java接口隔离原则实例分析
    这篇“Java接口隔离原则实例分析”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“Java接口隔离原则实例分析”文章吧。定义接...
    99+
    2023-06-29
  • Java设计模式七大原则之接口隔离原则详解
    目录定义案例需求方案一方案二对比分析总结小知识点相同点不同点定义 接口隔离原则(Interface Segregation Principle),又称为ISP原则,官方定义为 1.客...
    99+
    2024-04-02
  • Go语言中接口驱动容器设计的最佳实践
    在Go语言中,接口驱动容器设计是非常常见的设计模式,也是一种非常实用的设计思路。通过接口驱动,我们可以实现代码的高度解耦,使得代码的复用性、可维护性和可扩展性都得到了极大的提升。本文将介绍在Go语言中如何使用接口驱动容器设计的最佳实践,同...
    99+
    2023-09-29
    接口 容器 函数
  • 深入理解Go语言设计原理
    深入理解 go 语言的设计原理对于充分利用其强大功能至关重要,这些原理包括:并发性和 goroutine:go 语言通过 goroutine 实现并发性,允许并行执行代码块。通道:通道实...
    99+
    2024-04-03
    go语言 设计原理 并发请求 垃圾回收器
  • 设计java中的接口需要遵循哪些原则
    设计java接口的规范性建议:1.职责原则在设计接口时,必须明确接口的职责,即接口类型,接口应解决什么业务问题等2.单一性原则在明确接口职责的条件下,尽量做到接口单一,即一个接口只做一件事,而非两件以上。很多非资深接口设计者,在设计接口时,...
    99+
    2016-11-03
    设计 java 接口 原则
  • 不同语言中接口与Go语言接口的差异
    不同语言中接口与 Go 语言接口的差异 什么是接口? 接口是一种抽象概念,定义了一组方法或行为,而不需要定义这些方法的具体实现。接口允许程序员定义一组通用的规则或契约,而不管底层实现如...
    99+
    2024-04-12
    接口 go语言 python c#
  • Go语言正则表达式实例分析
    这篇文章主要介绍了Go语言正则表达式实例分析的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇Go语言正则表达式实例分析文章都会有所收获,下面我们一起来看看吧。前言在计算中,我们经常需要将特定模式的字符或字符子集匹...
    99+
    2023-06-30
  • Go语言的接口详解
    目录1、接口的用途2、类型断言3、类型选择4、空接口5、匿名空接口6、实现多个接口7、接口嵌套8、接口零值9、make和new的区别总结接口就是一系列方法的集合(规范行为) 在面向对...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作