可牺牲的架构
本文是翻译,版权归原作者所有
你坐在会议室里,凝视着你的团队在过去数年一直维护的代码。你已经做出了决定,你现在能够做的、最好的选择就是扔掉所有的代码,重建一个全新的架构。对于这些命中注定的代码、你投入其中的时间、此刻之前所做的那些决定,你该作何感想呢?
对于很多人而言,扔掉代码库是失败的象征,鉴于软件开发固有的探索性质而言是可理解的,但是,这仍然是失败。
不过,你现在能够编写的最好代码常常是你在数年之后要抛弃的代码。
我们经常把伟大的代码视作永久的软件。作为一名编辑,我写这篇文章时的身份可追溯到1980年。对于软件架构是 如何减轻某种永久 做了很多思考。然而你的成功可以建立在代码之上,因为被送到了 /dev/null。
想一下网络上最成功的大型商务网站之一的、eBay的故事。它在1995年用了一周时间,从一堆perl脚本开始。在1997年,它推翻一切,在当时的windows工具之上,用C++编写的系统取而代之。然后到了2002年,应用程序用Java重写了。早期的版本因为它们被取代了就成为了错误吗?很难这样说。eBay目前仍然是web上最伟大的一个成功,但是成功的大部分因素是建立在90年代被抛弃的那些软件上。就像很多成功的网站一样,eBay已经看到了指数级的增长,指数级的增长对于架构不是友好的。支持1996年eBay的合适架构,对于2006年eBay来说,就不是合适的了。1996年的架构无法处理2006年的负载,但是2006年的版本太过复杂而难以建立、维护,它是根据1996年的需求演化而来的。
的确,这个原则可以引出工作的一种组织方式。在Google,大家熟知的要求就是设计一个满足当前10倍需求的系统,这暗示着如果需求超过了一个数量级,那么扔掉并从头做起是更好的。每隔几年就被重新设计与抛弃的子系统而言,这是非常普遍的。
的确,我们通常可以看到,刚接手一个成熟代码库的人们诟病架构的性能和可伸缩性。但是在软件系统的早期阶段,你不一定要确保它真正需要做什么,关注灵活性以应付功能改变是十分重要的,而不是性能或可获得性。随着你的用户越来越多,你需要切换优先级了,不过让太多用户处在一个低性能的代码库,通常是优先级较高的问题,而不是优先级低。Jeff Atwood发明了一句话“性能是功能”,一些人把它理解成性能总是第一优先级。但是任何功能只是你不得不从其它功能选出的。这不是说,你应该忽视性能之类的工作——软件可以变慢、不可靠到断送一个业务——但是团队不得不与其它需求做出痛苦的抉择。通常有更多的业务决定,而不是技术上的决定。
那么这意味着要故意选择一个可牺牲的架构吗?本质上它意味着接受,因为若干年后你将(如果顺利的话)扔掉当前创建的东东。这说明了要接受你堆放在一起的、跨功能需求的限制。这也说明了现在需要考虑,当这一刻到来的时候,如何能够让其变得容易——软件设计师很少考虑如何设计他们的创造,以支持将来的优雅替换。这也意味着在相对短的时间内被扔掉的软件,仍然带来了很大的价值。
明白了你的架构是可牺牲的,不代表要放弃软件的内部质量。通常,被牺牲掉的内部质量,将比替代时间更早地伤害到你,除非你已经工作在行将退役的代码库上。良好的模块化是健康代码库的关键部分,模块化通常在替换系统时起到巨大的帮助。对于系统的早期版本,要做的最好的一项工作就是搞清楚什么是最好的模块化结构,为将来的替换做准备。虽说在早期牺牲一整个系统是合理的,但是如果具备良好的边界,随着系统的增长,牺牲单个模块是更有效率的。
处理这个问题时,容易忽略的一个方面就是结算。是的,真的如此——我们已经陷入 人们不情愿替代一个明显的、不可行的系统 的状况,因为他们正在分期偿还代码库的方式。对于大企业,这更像是一个问题,但是不要忘了,只要你生活在这个世界上,就要去检查一下。
你还可以把这个原则应用到现有系统的功能上。如果你正在开发新功能,那么只让一部分用户可见是明智的,因为你能够得到 它是不是一个好想法 的反馈。为了达到这个目的,开始的时候,你可能在以一种可牺牲的方式在开发,你不必在一个功能上投入全力,因为你可能发现它不值得全面部署。
模块可替换性对于微服务是一个主要论据,但是我谨慎推荐可牺牲的架构。微服务暗示着分布和同步,它俩都是复杂的助推器。我已经碰到过一些项目,它们在走不是真正需要的微服务道路——结果严重减缓了它们的功能管道。因此,借助后来引入的微服务,逐渐将庞然大物分解,而庞然大物经常是好的可牺牲架构。
编写可牺牲架构的团队要决定牺牲它的时机。对于接手的新团队而言,他们讨厌现有代码、想重写,这是不同的情况。如果你没有理解已编写代码的上下文,你很容易就厌恶你没有编写的代码,明白你将要编写的代码属于可牺牲的代码,将是一个有用的变数。
致谢
- 与Randy Shoup的谈话启发了我,并帮助我构思了本文,尤其是eBay(和一些Google的类似故事)的历史描述。 Jonny Leroy指出了结算问题。Keif Morris, Jason Yip, Mahendra Kariya, Jessica Kerr, Rahul Jain, Andrew Kiellor, Fabio Pereira, Pramod Sadalage, Jen Smith, Charles Haynes, Scott Robinson and Paul Hammant 提供了有帮助的评论。
原文地址:http://martinfowler.com/bliki/SacrificialArchitecture.html
译文: 《可牺牲的架构 》| 腊八粥