
上QQ阅读APP看书,第一时间看更新
2.4 使用接口和契约
接口是软件工程师可以使用的最佳工具之一。将某些内容公开为接口后,你可以自由地更改其背后的实现。接口是在单个进程中使用的结构,它们对于测试与其他组件的交互非常有用,而在基于微服务的系统中,这些组件会非常丰富。以下是示例应用程序的一个接口:


UserManager接口定义了一些方法、输入和输出。但是,它没有指定语义。例如,如果为已经登录的用户调用Login()方法会怎样?会报错吗?上一个会话是否会终止并创建新会话?是否返回现有会话而没有报错(幂等方法)?契约可以回答这类问题。契约很难完全指定,并且Go不为契约提供任何支持。但是,契约很重要,即使它们只是隐含的,契约也始终存在。
某些语言不支持接口作为该语言的一级语法结构,但是,实现相同的效果非常容易。具有动态类型的语言(例如Python、Ruby和JavaScript)使你可以传递满足调用者使用的属性和方法集的任何对象。静态语言(例如C和C++)通过一组函数指针(C)或仅具有纯虚函数(C++)的结构来获得。