这里谈及在代码设计阶段以及重构阶段要考虑的架构方面问题,可以说是开发过程中的中层阶段;
主要是将
- < the art of unix programming>
- < clean architecture>
- < the pragmatic programmer>
- < design patterns>
等几本书结合实践做一个融合总结,一些书在architect上面开始大量重复了(e.g. 《code complete》等)这里略过,大师们的看法也是高度相似的;
principle-pattern-practice
如果谈到如何去做程序设计,和大多数领域知识类似,遵循抽象的层级:principle-pattern-practice;
或者[dikw]
这种的数据到智慧的抽象模式,越往智慧级别的事情抽象就越干练关键;
复杂度&生产力
这个在本blog已经谈及很多次了,也是我个人会把《the art of unix programming》列为基本讲程序设计的书之首的原因;
书中在讲了程序设计的哲学,以及大量unix设计的模块之后,总结的时候,会说这本书归结到一点的话,就是KISS原则;
但是个人还是更推崇其中的一句话:“Controlling complexity is the essence of computer programming”
KISS因为说的太多,而且描述过于“轻松”,逐渐变成了依据“正确的废话”了,大家都知道,但是已经不再实质性遵守;
而“Controlling complexity”则在日常的开发中,给我更多的启示,也是我和team lead们工作的重心,就是反复审视系统,来看复杂度上是否有做到最简;
< clean architecture >中关于architecture的论述中,有两点觉得比较遗憾:1,没有谈及生产力,更多的把architect论述为未来扩展性和变化特性而准备;2,没有围绕复杂度来将整本书串起来。
复杂度->生产力->成本
复杂度高到一定程度的时候,项目中的整体关键开发因素开始和复杂度成正比:
- 开发成本
- 稳定性
真正到了“屎山”的程度,开发成本开始接近无限大了,稳定性进入脆弱的平衡。
两个可以解耦的系统,分离状态复杂度是m+n,搞砸了揉到一起就是m*n,最后就会编程项目的成本和稳定性问题,这个就是架构设计的现实意义。
beyond 架构设计
当然手握复杂度这个终极评判标准,在复杂度尚可的时候,违反设计原则就无所谓了。
如果只是几个人的短期项目,或者demo阶段,这个时候去遵照设计模式就不会带来实际收益,如果还要拉长开发时间的话,那就果断“违纪”吧。
控制和变量
整体上< clean architecture >依旧是非常卓越,关于“控制”和“变量”的论述让人眼前一亮。
说来确实很神奇,从60多年前,编程这件事情开始以来,很快在30-40年间开始逐步稳定,其中的洞见几乎被发掘充分了。
通过编程落地的“知识”(人工智能,图形学等等)还在快速发展,但是编程这件事情本身,已经发展接近充分了,我们也可以发现带来洞见的编程数据在2000年前后一波爆发之后,近20年来也不多了。
那么早期的三种编程模型,就带来了对于控制和变量的三种限制:
- 结构化编程(也就是if else这种,不要goto):限制了直接的控制转移
- 面向对象编程(主要是多态):以安全的方式实现多态(取代了函数指针),因此限制了间接的控制转移(函数指针),最后带来了插件式构建系统的可能,让面向接口开发(而不是面向实现开发)成为可能;
- 函数式编程(主张不做变量赋值的pure function):限制了变量的赋值,变量的赋值是万恶之源,尽量限制;
三种限制带来三种关键的对于复杂度的控制;
边界和分层
然后编程的事情,就是更多探讨边界和分层方式的问题;
patterns
solid原则
这个大家很熟悉了,但是觉得可以再精简一些:
- Single responsibility principle:责任单一,中文更精炼一些:高内聚,低耦合;
- dependency inversion principle:面向接口(抽象)编程,而不是实现编程,这里让抽象变得分离的更清晰,降低了系统的复杂度;
composition over inheritance
同标题,也是有效的降低了复杂度;
others
然后就是design patterns里常用的设计模式了;
不一一列举了;
架构的终极负责人
就是技术lead;
事关技术的生产力和团队研发成本,搞砸了出现问题,技术lead站出来对此事负责,认定这一点,好于其他一切;