假设你要处理一段业务请求(随便什么业务请求都行),然后返回一个结果,这里的请求和结果不妨称之为request和response。在返回结果之前,可能还要再写点文件/OSS/ODPS/数据库之类的东西——这是个很通用的场景模型,绝大部分相对耗时的异步服务,都能归类于此。  在实际开发中,事情往往比较繁琐且无趣:request的处理过程,很多时候都会涉及到十几二十个中间变量,它们有一些来自于request直接带进来的信息,有一些是根据request信息拉取的OSS文件,有一些来自于访问数据库拿到的结果,还有更多的是你为了数据过滤、分组、匹配或者单纯就是DTO转换而创建的各种临时list, set, map,它们很可能还分散在不同的类里,你需要将引用到处传来传去。这件事情有多么烦人多么脏且累,相信写过业务代码的朋友都懂。  对于复杂业务,稍微好一点的方式,是把所有的中间数据,全部丢进一个上下文也即Context里。要传递就只用传递这个上下文,要取数据就只从这个上下文里取,这样可以一定程度缓解数据凌乱给你造成的焦躁感,也能有效降低过多引用传递带来的心智负担和工程复杂度。  然而事情远没这么简单,随着这个上下文里的东西越来越多,这些数据彼此间的依赖关系越来越复杂,新的麻烦又出现了——先创建谁,后创建谁?这几十个临时变量,有的有直接由上游过滤得到,有的需要对两个set取交集,有的需要根据一个map从另一个list里进行匹配,有的要等很长时间的IO从 OSS 里下载,有的则来自于 kconf 的静态配置。你得小心翼翼,确保每一个临时变量创建的时候,它的上游依赖已经全部准备妥当,不然就等着各种NPE崩你脸上吧。  总之,抽象来看,这所有的中间变量,必然构成一个有向无环图。你写业务逻辑的过程,本质上就是在手动对这个有向无环图进行拓扑排序。示例如下: