一文搞懂接口隔离原则

定义

客户端不应该被强迫依赖它不需要的接口,这里的客户端指接口的调用者

接口可以理解为下面三种东西:
一组API接口集合
单个API接口或者函数
OOP中的接口概念

一组API接口集合

一组API接口集合指的就是微服务或者类库
比如开发一个用户系统微服务,提供了一组和用户相关的接口给外部系统使用

type UserService interface {
	Register(username string, password string)
	Login(username string, password string)
	GetUserInfoByID(id string)
}

此时后台管理系统有一个删除用户的需求,那么这个删除用户接口可以直接加在UserService中吗?
DeleteUser接口涉及用户删除,是一个安全性要求非常高的操作,只能由后台管理系统调用,其他系统不能调用,如果直接加在UserService中,UserService的其他调用方就也可以调用DeleteUser接口了
如果有接口鉴权框架,那么加在UserService中没有大问题,我们可以通过接口鉴权框架限制DeleteUser接口的调用方,防止UserService的其他调用方调用该接口
如果没有接口鉴权框架,我们就只能从代码层面限制DeleteUser接口的调用,将DeleteUser接口拆分到一个单独的RestrictedUserService中,只将RestrictedUserService暴露给后台管理系统,不暴露给其他系统,这样UserService的调用方就无法调用DeleteUser接口

微服务或者类库,如果它们中的某些API接口只被某些调用方使用的话,那么应该将这些API接口隔离出来,单独提供给那些调用方使用,而不是强迫其他调用方依赖这些用不到的接口

单个API接口或者函数

比如有一个统计信息的函数Count

type Statistics struct {
	max           int
	min           int
	avg           int
	sum           int
	percentile99  int
	percentile999 int
}

func (s *Statistics) Count(data []string) {
	//根据data统计各种数据
}

这个Count函数就包含多个统计功能,统计最大值、最小值、平均值等等
如果使用到统计信息的地方,都是需要获取所有种类的统计数据那么Count函数可以认为职责单一;如果使用到统计信息的地方,都是只需要某一些种类的统计数据,比如只需要最大值、最小值等等,那么Count函数的职责就不单一,使用Count函数会增加一些多余的计算,降低性能,所以应该将Count函数拆成多个种类数据的单独统计函数,例如Max、Min、Avg等等

如果单个函数内部的某些功能只被部分调用者使用,那么应该将这些功能隔离出来,单独提供那些调用者

OOP中的接口

我们现在依赖Redis、Kafka、Mysql三个中间件,维护了三个中间件的Config,我们希望Redis、Kafka的配置具体热更新功能,Kafka、Mysql的配置具备可视化功能

type Updater interface {
	Update(path string)
}

type Viewer interface {
	OutputInPlainText()
}

type RedisConfig struct {
	Address string
	MaxCon  int
	MinCon  int
}

func (c *RedisConfig) Update(path string) {
	println("加载配置文件更新配置")
}

type KafkaConfig struct {
	Address string
	MaxCon  int
	MinCon  int
}

func (c *KafkaConfig) Update(path string) {
	println("加载配置文件更新配置")
}

func (c *KafkaConfig) OutputInPlainText() {
	println("可视化展示配置")
}

type MysqlConfig struct {
	Address string
	MaxCon  int
	MinCon  int
}

func (c *MysqlConfig) OutputInPlainText() {
	println("可视化展示配置")
}

我们这里维护了两个单独的接口Updater、Viewer,需要热更新的Config实现Updater接口,需要可视化展示配置的Config实现Viewer接口,而不是采用一个大一统既包含热更新又包含可视化配置的Config接口
好处是:

  1. 接口的功能越单一,可复用性越强。比如我们又要开发一个Metrics性能统计模块,并且希望Metrics可以具备可视化展示功能,尽管Metrics和Config无关,也可以让Metrics实现Viewer接口即可
  2. 省去一些代码实现上的无用功。如果使用Config接口,RedisConfig不具备可视化配置功能还需要去实现OutputInPlainText方法,同理MysqlConfig不具备热更新功能还需要去实现Update方法;而且接口功能越单一,接口的实现类越少,接口变动时需要修改的类更少
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值