From 12ee66dfdfef2cb1b209173584a149ff01d2a1ce Mon Sep 17 00:00:00 2001 From: Xargin Date: Fri, 23 Mar 2018 18:05:08 +0800 Subject: [PATCH] add headers --- ch6-web/ch6-08-protocol-free.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/ch6-web/ch6-08-protocol-free.md b/ch6-web/ch6-08-protocol-free.md index 5a86044..2e25f23 100644 --- a/ch6-web/ch6-08-protocol-free.md +++ b/ch6-web/ch6-08-protocol-free.md @@ -4,6 +4,8 @@ 如果对于我们的服务模块,提出了更进一步的要求,想要同时支持 http 和 thrift 协议。要怎么办。 +## clean architecture + 在 Uncle Bob 的 《Clean Architecture》 中对插件化架构(plugin architecture) 的阐释能够给我们一些启示。我们先来看看什么是“插件化架构”。 ![插件化架构](../images/ch6-08-plugin-arch.jpg) @@ -20,6 +22,8 @@ type RecordStore interface { 比较典型的应用,例如你们公司的服务原来是 C/S 架构,在 web 2.0 时代突然流行起了 B/S 架构,然后在移动互联网的浪潮下又开始流行 C/S 或者一些 hybrid app 架构,但是这些变化对于后端程序来说,大多数的代码应该能够做到置身事外。再比如你们公司之前因为技术升级,可能多次切换底层存储,但在存储迁移过程中,哪怕是 dao 层的相关代码要做一些修改,这些修改的影响也不应该侵入到业务逻辑层。 +## interface 应用 + interface 的最大好处,就是帮我们完成了这样的依赖反转。针对本节的处理协议的场景具体要怎么做呢?假如我们现在有一个下订单的需求,我们可以在 logic 层(或者叫 service 层) 定义一个 interface: ```go @@ -102,6 +106,8 @@ func HTTPCreateOrderHandler(wr http.ResponseWriter, r *http.Request) { 这样在对协议层进行修改时,就可以对 logic 层没有任何影响了。像前面提到的,这样的做法我们同样可以用在 logic 和 dao 层的交接处,也没有什么问题。 +## codegen 来实现同样的功能 + 当然,如果完全按照 clean architecture 的设计来写代码还是有一些麻烦。在可预见的范围内,我们需要处理的协议类型是有限的。现在互联网公司内部 API 常用的就只有三种 gRPC、thrift 和 http。我们甚至可以通过一些手段,使我们每写一个接口,都可以支持这三种协议。先来把 logic 的入口简化一些,这里我们使用生产环境的 logic 函数签名作为样例: ```go