年底了, 趁着闲暇,想写点什么。
2019年,很开心这一年又坚持看了很多书。如果让我找到一本收获最大的,无疑是《演示式架构》。薄薄的138页,我反复了看了很久,也在工作中体会到了作者提出这个美妙的词汇——“演进”。我之前看了很多相关的书籍,我看到过“架构是经验主义”(《架构之美》),“整洁架构”,我能从里面体会到项目分层和权职划分的妙处,但直到看过这本书,才体会到,是有一些技巧去权衡和选择项目架构设计的方法论的(其实,直到1年多以前,我都还体会不到很多概念该怎么应用到实践中),当然这真的是需要体会和打磨的。
我想整理下这本书中学到的和在项目中体会到的一点点方法和经验,当然,这只是我阅读了2遍左右的收获,也可能仅仅适用于移动端的敏捷开发,仅供参考,别被误导了哈,不到之处欢迎批评。对了,这里没有到具体细节,因为很多公司分享过的演进过程更有参考价值(印象比较深的:微信、美团、安居客)。
《演进式架构》:
1. 架构师应不断的对项目进行平衡,以适应环境的变化。
2. 架构师应不断的关注团队的关系,让架构适应团队的合作方式,符合“康威定律”。
3. 架构是不断努力的结果,是一个与开发工作紧密结合的过程,这样它才能同时响应不断变化的需求和开发人员的反馈。我们称之为“演进式架构”,正是要强调当无法预测变化时,该架构仍然可以朝着正确的方向发展。
4. 演进式架构的核心是采取小步骤变更,然后通过反馈环,让团队的每个成员从系统地发展过程中学习。持续交付的兴起使得演进式架构变得切实可行。
5. 大泥团架构、单体架构、事件驱动架构、服务导向架构、“无服务”架构。
注:如果开发人员难以构建最简单的架构,那么转向更复杂的架构并不能解决问题。
6. 适应度函数:现实架构由很多不同的维度构成,包括性能、可靠性、安全性、可操作性、代码规范和继承等方面的需求。我们需要适应度函数能代表每一项架构需求(开发人员由多种描述是硬度函数的机制,比如测试和衡量指标)。
敏捷开发的思路让一个项目可以快速迭代,演进式架构,无疑是为适配敏捷开发的绝好工具,一直在往前走,所以一直在调整,永不过时。之前接触过“微服务”、无服务的设计,一直在尝试是否能在项目里实践,可是上面“注”的那句话太好了,这些结构可以是演进过去的,永远不要觉得换结构就能解决目前的问题。
在迭代中我是怎么实践演进的实践的?
1. 在需求演讲阶段(产品时主角),发现代码中的痛点,并制定重构计划,将重构任务尽量适配到迭代版本中(分步骤切分到多个版本中),达到持续交付、随时线上验证设计(当然,这个很考察开发人员对项目和编码的熟练度,别挖坑,别挖坑,慎之又慎是关键!!!但是,要大胆,这样才能做出事情);
2. 在review和日常工作中,收集开发人员对业务层、业务管理层、数据层接口的痛点,并搜集大家期待的舒服访问方式,考虑进行重构;主动接收项目中维护困难的部分,重写或重构其实现,减少阅读和维护成本;
3. 在开发过程中,发现业务层可下沉到数据管理层的部分,在繁重的迭代任务后尽快适配到目前的设计结构中,减少业务层的代码难度;
(处于原型期的项目)
对于一个新项目,早期的迭代,实现的优先级是大于编写整洁代码的(以前我也觉得我的精力绝对可以一直把做对和做好兼顾到。但是实践证明,时间不等人,人的精力真的是有限的,做好真的是需要不断积累的,毕竟还是能抽出时间做好的),繁重的开发任务甚至让大家无暇去考虑重构。但是,相信一点”早期项目架构的整洁更是能为后面的迭代节省大量的时间”。我们可以在迭代初期以一种先实现的思路去做好功能(这个时候,分层的考虑、自上而下的访问等规则甚至都难以保证),这就好比先忍受让一棵树木,四处乱长,但是我们需要及时(这个词汇太重要了!别等,等就会越来越多!)、不断的进行修剪,让其尽量美观;早期的项目嘛,不得不面对较多的设计错误。在一个版本提测后犯错误的成本是比较低的,这时候为重构和设计提供了较充分的时间;一定要利用好这段空闲时间,果断的进行重构和打磨,让代码保持到尽量整洁,这样的工作绝对不是一直持续的,因为几次的重构我们会积累下经验,慢慢的在迭代中去考虑设计,可能需要重构的代码会越来越少;这样下一版、下下一版的扩展和修改成本才会越来越低。在测试后改结构,测试很多时候是无感知的哦,要小心!
(处于增量期间的项目)
我觉得《设计模式:可复用面向对象软件的基础》最后一章对于怎么维护这样的项目讲的挺好的。
做演进式设计,就是个“积跬步成千里”的过程,而重构是一直在用的锋刃利器,能较敏锐的发现重构和实践重构是我一直在追求和实践着的。实践证明,追求好的过程中一定会受到吐槽和阻拦,但是先对事,解决问题后重新审视问题并丰富设计的方式可以更从容的应对这些矛盾。我将重构划分为三个层次:函数级别的重构,类级别的重构和体系结构重构。
函数级别的重构,旨在提高减少阅读成本(让注释显得多余),让修改变得简单(应对散弹式修改),事不过三(重复的代码不写三遍,当然,重复有时候会优于整合,这是个权衡问题)。比如:为减少注释而新建的函数、为减少代码行数而划分的小函数等(减少维护者在代码处的停留时间);
类级别的重构,以前很多人都提到了设计模式等概念纠结太多会提高复杂度,甚至提出了反模式。我记得一本书上说过:所有的反模式都是可以使用设计模式更好的实现的。我记得有这样的一个理论,当你觉得有一个反人类的设计时,也许是你走入死胡同了。我个人一直在向身边的朋友建议,也许这并不是解决问题最好的思路,你可以尝试接受一下XX设计的思路也会可以更好的解决问题呢。对了,分享一个设计模式绝好的项目:https://github.com/iluwatar/java-design-patterns ,参与这个项目很久了,这里有上百个大家多年工作和总结后的模式,并解决了很多经典23设计模式的缺陷,我个人觉得这是做类级别重构的绝好学习资料,尽量阅读完,收获绝对是非常非常大的。
体系结构的重构。这块我还是在摸索,以我的水平,暂时只是参考google等提供的分层设计并找出部分问题尝试修改的阶段,这其实还是第二级吧。从一个分层设计切换到模块化设计,甚至到现在主流的微服务设计,没经历过(也是因为项目的痛点没体现到导致的吧),我能体会到这一定是大量功能的重写支撑起来的,我从网上的文章中看到过美团外卖android和微信android曾经分享的体系结构的重构,还是挺成功的,过程耗时0.5-1年左右,我吸收了他们的经验,但不太适合我所经历的小、中型项目,其实主要也违背了“架构要适应组织结构的变化”。