You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

4.8 KiB

说点题外话04面向对象的原则适用于RESTful API吗

你好,我是徐昊。今天我们再来专门说点题外话。

前面几期题外话都比较偏向于提供一种不同的角度主要是因为你们也并没有针对课程的内容提出什么特别的问题需要我来具体回答。那么作为我们在进入新约前的最后一篇题外话我想聊一聊关于RESTful API的问题。

我记得有位同学在留言区问了这样一个问题过长的URI是否破坏了迪米特法则Law of Demeter。这里我们就要搞清楚什么是迪米特法则呢

迪米特法则又叫最小可知法则,指的是在面向对象设计中,实体应尽可能少地与其他实体发生交互。为了说明什么是“少的交互”,我们还特别归纳了一组可以认为不违反迪米特法则,并且可以直接调用的对象:

  • 当前对象自己thisself
  • 以参数形式传入的对象比如函数的形参parameter
  • 当前对象内实例变量引用的对象instance variable
  • 如果实例变量是集合那么集合中的对象也可以访问collectionaggregration
  • 由当前对象创建的对象variable declaration in function

那么这些场景适用于RESTful API调用的场景吗显然并不太适用。因为在RESTful API的场景中实体只有客户端和API提供者而API提供者的内在结构都被API层屏蔽了。所以无论怎么调用都不会出现对于API提供者内部结构的依赖。

如果我们把迪米特法则扩展一下推广到概念层面暴露了内在的逻辑就算。那么恰恰是RESTful API能帮助我们继续遵循迪米特法则。

比如通过超媒体明确地表示资源之间的关联而不是依靠客户端去拼凑URI。如果客户端可以拼凑出URI则表明客户端对于API提供者的内在逻辑存在依赖。而通过HATEOAS把所有关联的链接直接提供就避免了暴露内在的逻辑。

再比如API的设计要按照HTTP语义约定而不是客户端与API供应者之间的“私约”private protocol。PUT只能修改已经存在的资源而不能构建新的资源POST创建资源成功需要返回201并在HEAD中给出新构建资源的URIGET默认都是可以缓存的无法缓存的查询而不是通过URI遍历信息需要用POST访问等等。这些都是希望通过公约将客户端中对于API供应者的了解降到最低。

所以迪米特法则本身的想法是不错的但是场景改变了我们就要重新思考它在新的环境中是如何被应用的。而如果我们真的在乎迪米特法则那么在RESTful API的场景下关注点就不会放在URI有多长上而应放在客户端与服务器间的知识依赖到底有多少上。

另外一个对于RESTful API的质疑在于通过HATEOAS完全以分布式超媒体的方式构成API那么客户端看起来越来越像浏览器而不是针对RESTful API的客户端了。

正如我们在第10讲中讲到的RESTful架构风格是对互联网架构的反思。那么互联网架构的核心在于开放性和扩展性,因而RESTful架构风格的核心也是开放和扩展性

因为开放使得RESTful API的供应者不会对客户端作出任何假设。就好像互联网服务器并不会假设它的客户端只有浏览器一样wget、telnet等等都是可能的客户端而因为扩展性RESTful API只会为客户端提供最基本的功能大量的计算被分布到了客户端侧进行。

这种架构的假设是不同于企业应用的客户端与服务器架构的,在企业应用架构的语境中,客户端与服务器有更多的耦合。服务端更多地是为客户端提供服务,而不是保持自己开放和稳定。

那么为什么RESTful API最终还是成为“行业主流”了呢虽然真的会和真的用的人并不多

因为从大趋势上来说将企业内的能力而不仅仅是后台构造成开放API并围绕着开放API形成企业内生态是大势。在这个大势之下RESTful API、MicroService、企业内生态、能力平台、中台形成了一条清晰的企业架构现代化之路。仅仅服务于某些或者某个前台的后台服务终将会淡出历史的舞台。

因而在这种历史转折的节点,我们更应该清晰地理解不同想法之间的差异,哪怕它们要解决的问题与现行方法是相似的,但是对于这是什么问题,我们要怎么想,还是带来了完全不同的角度。

思考题

请问其他面向对象原则与最佳实践在RESTful架构下有何种体现

欢迎把你的思考和想法分享在留言区,我会和你交流。我们新约部分再见!