加载中...

本篇要回答的问题:到底什么是"接口"?接口的两种含义——模块的使用界面模块的环境依赖——分别应该遵循什么准则去设计?

上一讲 OCP 强调"模块业务要稳定、变化点用接口/插件开放出去"。本讲承接这一点,把"接口"这个天天挂嘴边的词用科学家的严谨拆开:接口在不同语境下有两层含义,一是模块的使用界面(规格),二是模块对依赖环境的抽象(契约式设计)。两者各有准则。

接口的两种含义

含义 别称 一句话
模块的使用界面 规格 公开的类/函数原型,应自然体现业务需求
模块的环境依赖 契约 模块与模块之间的契约,基于接口而非具体实现(Design by Contract)

模块的使用界面:KISS 原则

使用界面最重要的是 KISS(Keep it Simple, Stupid)——让傻子也能看懂,简单自然、符合惯例。以七牛 mockhttp(不真启动 HTTP 服务、无端口占用的测试库)两版接口对比:

版本 接口 问题 / 改进
mockhttp.v1 func Bind(host, service interface{})var Client rpc.Client 违反 SRP(既启服务又做路由分派);Bind 不合 Go 惯例;Client 类型 rpc.Client 带来多余依赖,应叫 DefaultClient
mockhttp.v2 func ListenAndServe(host, service http.Handler)var DefaultClient *http.Client Go 程序员一看即明,与标准库 net/http 自然融合

关键判断:接口要 KISS,很重要的一点是符合语言和社区的惯例。某类业务若语言里已有约定俗成的接口(如 ListenAndServe),就尽量沿用相同语义。所有的偷懒总会还回来——v1 的随意最终逼出了 v2 重写。

模块的环境依赖:最小依赖原则

环境依赖遵循 最小依赖原则 / 最少知识原则(LKP),尽力发现并去除多余依赖。环境依赖分两种,处置方式不同:

依赖类型 含义 处置重点
使用界面依赖 用模块使用界面时自然涉及的 参数泛化与抽象,适应更广场景
实现依赖 当前实现方案涉及的组件,换方案就可能消失 默认直接依赖组件,必要时才抽象成接口

参数泛化:恰如其分,别过度

  • 好的泛化:IO 接口把 *os.File 换成 io.Reader/io.Writer,顺带支持剪贴板。
  • 伪泛化要警惕Bind(..., interface{}) 看似比 ListenAndServe(..., http.Handler) 更泛化,实则 v1 内部靠反射做路由分派,假设更强、场景反而收紧了。
  • 过度泛化是过度设计:不会发生的泛化就别做。让系统足够简单又不失扩展性,平衡全靠对业务的理解。

实现依赖:如无必要,勿增实体

关键判断:大部分情况应直接依赖组件,不必抽象。大量抽象基础组件会提升可配置性,但也抬高学习成本。

什么时候才该把实现依赖抽象成接口:

场景 例子 注意
需要提供多种选择 Logger 组件,决策权交使用方 但抽象数据库以便 MySQL/MongoDB 自由切换多属过度设计——选数据库本应慎重
解除庞大外部系统依赖 测试时 mock 掉重外部依赖 降低测试系统依赖
依赖的是可选组件 初始化时把接口设为 mock 组件 用户不关心就当它不存在,降低学习门槛

对实现依赖做接口抽象,本质是给模块配置化、增加配置项,需谨慎、适可而止。

总结

接口有"使用界面"和"环境依赖"两种理解,各对应一条准则。一句话:使用界面追求简单自然合惯例,环境依赖追求够用就好别多依赖

先把"是什么"回答清楚

概念 一句话说明
使用界面 模块的规格/原型,准则是 KISS、符合惯例
环境依赖 模块间契约,准则是最小依赖/最少知识(LKP)
使用界面依赖 用接口时自然涉及的依赖,靠参数泛化处理
实现依赖 当前实现引入的依赖,默认直接依赖、必要才抽象
过度设计 为不会发生的泛化或灵活性付出的复杂度成本

一句话速记

使用界面用 KISS 跟着社区惯例走,环境依赖用 LKP"如无必要勿增实体"——泛化和抽象都要恰如其分,过犹不及。

几条值得记住的判断

  • 符合社区惯例比"自创一个简单接口"更 KISS。
  • 看似泛化的 interface{} 可能是场景收紧,要看背后假设。
  • 抽象实现依赖 = 配置化,只在"多选择 / 解重依赖 / 可选组件"三种场景才做。

思考题

审视你最近写的一个公共接口:它的参数类型是恰如其分,还是为了"灵活"用了过度泛化的 interface{} / 抽象层?如果删掉这层抽象、直接依赖具体组件,会损失什么真实存在的能力吗?

公告栏
这是我的个人知识库。
记录技术,也记录生活 —— 读过的、试过的、想明白的,都堆在这儿。
最新文章
网站资讯
文章数目 :
5
已运行时间 :
本站总字数 :
15.7k
本站访客数 :
本站总访问量 :
最后更新时间 :
全局知识图谱
当前页面 已访问 文章 标签
ESC 关闭 · 滚轮缩放 · 拖拽移动 · Ctrl+G 开关