mirror of
https://github.com/chai2010/advanced-go-programming-book.git
synced 2025-05-24 12:32:21 +00:00
update if
This commit is contained in:
parent
b0bbd1c892
commit
674763ecb9
@ -14,9 +14,41 @@
|
||||
|
||||
互联网公司只要可以活过三年,工程方面面临的首要问题就是代码膨胀。系统的代码膨胀之后,可以将系统中与业务本身流程无关的部分做拆解和异步化。什么算是业务无关呢,比如一些统计、反作弊、营销发券、价格计算、用户状态更新等等需求。这些需求往往依赖于主流程的数据,但又只是挂在主流程上的旁支,自成体系。
|
||||
|
||||
这时候我们就可以把这些旁支拆解出去,作为独立的系统来部署、开发以及维护。这些旁支流程的时延如若非常敏感,比如用户在界面上点了按钮,需要立刻返回(价格计算、支付),那么需要与主流程系统进行 RPC 通信,并且在通信失败时,要将结果直接返回给用户。如果时延不敏感,比如抽奖系统,结果稍后公布的这种,或者非实时的统计类系统,那么就没有必要在主流程里为每一套系统做一套 RPC 流程。我们只要将下游需要的数据打包成一条消息,传入消息队列,之后的事情与主流程一概无关(当然,如果与用户的后续交互流程还是要做的)。
|
||||
这时候我们就可以把这些旁支拆解出去,作为独立的系统来部署、开发以及维护。这些旁支流程的时延如若非常敏感,比如用户在界面上点了按钮,需要立刻返回(价格计算、支付),那么需要与主流程系统进行 RPC 通信,并且在通信失败时,要将结果直接返回给用户。如果时延不敏感,比如抽奖系统,结果稍后公布的这种,或者非实时的统计类系统,那么就没有必要在主流程里为每一套系统做一套 RPC 流程。我们只要将下游需要的数据打包成一条消息,传入消息队列,之后的事情与主流程一概无关(当然,与用户的后续交互流程还是要做的)。
|
||||
|
||||
通过拆解和异步化虽然解决了一部分问题,但并不能解决所有问题。
|
||||
通过拆解和异步化虽然解决了一部分问题,但并不能解决所有问题。随着业务发展,单一职责的模块也会变得越来越复杂,这是必然的趋势。一件事情本身变的复杂的话,这时候拆解和异步化就不灵了。我们还是要对事情本身进行一定程度的封装抽象。
|
||||
|
||||
最基本的封装过程,我们把相似的行为放在一起,然后打包成一个一个的函数,让自己杂乱无章的代码变成下面这个样子:
|
||||
|
||||
```go
|
||||
func BusinessProcess(ctx context.Context, params Params) (resp, error){
|
||||
ValidateLogin()
|
||||
ValidateParams()
|
||||
AntispamCheck()
|
||||
GetPrice()
|
||||
CreateOrder()
|
||||
UpdateUserStatus()
|
||||
NotifyDownstreamSystems()
|
||||
}
|
||||
```
|
||||
|
||||
不管是多么复杂的业务,系统内的逻辑都是可以分解为 step1 -> step2 -> step3 ... 这样的流程的。
|
||||
|
||||
每一个步骤内部也会有复杂的流程,比如:
|
||||
|
||||
```go
|
||||
func CreateOrder() {
|
||||
ValidateDistrict() // 判断是否是地区限定商品
|
||||
ValidateVIPProduct() // 检查是否是只提供给 vip 的商品
|
||||
GetUserInfo() // 从用户系统获取更详细的用户信息
|
||||
GetProductDesc() // 从商品系统中获取商品在该时间点的详细信息
|
||||
DecrementStorage() // 扣减库存
|
||||
CreateOrderSnapshot() // 创建订单快照
|
||||
return CreateSuccess
|
||||
}
|
||||
```
|
||||
|
||||
在阅读业务流程代码时,我们只要阅读其函数名就能知晓在该流程中完成了哪些操作,如果需要修改细节,那么就继续深入到每一个业务步骤去看具体的流程。写得稀烂的业务流程代码则会将所有过程都堆积在少数的几个函数中,从而导致几百甚至上千行的函数。这种意大利面条式的代码阅读和维护都会非常痛苦。在开发的过程中,一旦有条件应该立即进行类似上面这种方式的简单封装。
|
||||
|
||||
## 使用 interface 来做抽象
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user