程序猿行动指南
文章目录
序
工作几年的你,与应届生比,除了经验多一点,还有什么不同?
——仅仅积累技术经验是不够的,要看清问题本质,掌握更高阶的理论,提升认知水平,这才能让你游刃有余,与众不同。
本文档争取从问题本质出发,为技术人员的成长,带来一点有价值的东西。
架构
1. 生命周期
【零】
佛曰“生住异灭”。
所有事物的变化皆为:从出生开始,成长完成,渐渐衰退,最终消亡结束。
近代出现所谓生命周期(Life Cycle)的概念,可简称为“生灭”。
【一】
生命周期,无处不在,从吃一口饭,到捡起一支笔,到眨一下眼睛,(从一个API,到一个Service,到一个Function,……)都是一个生灭,都是一个生命周期。生命周期不是孤立的,生命周期里包含生命周期,一个生命周期消亡会产生另一个生命周期。
【二】
生命周期,总有一个主体,可以是人、事、物。
【三】
生命周期(S),可以拆分。
拆分后,形成若干个新的子S,每个新S都有自己的主体,且都有自己的边界,各自的变化都在自己的生命周期内确定。
【四】
拆分后,主体不变的子S属于核心S,主体改变的子S属于非核心S,且核心S变得简短。
发现核心S(s)的过程,就是发现“内聚”的过程。(“高内聚”是指一个软件模块是由相关性很强的代码组成,只负责一项任务,也就是常说的单一责任原则。这是软件工程中的概念是判断软件设计好坏的标准。)
【六】
非核心生命周期一旦拆分出来后,往往变成了一个通用的服务。
原有的大生命周期变得精简,可以更加专注于自己的核心生命周期活动,节省更多时间。
空间连续的限制,可以通过生命周期拆分来打破,形成空间的并行、时间上的串行。
2. 理由
把其他能够被替代的生命周期并行起来,同样的时间内做更多的事情,相当于延长了自己的生命!
3. 定义
【一】
如果没有生命周期的拆分,就不能算架构。
【二】
特点:
- 边界:问题确定生命周期,问题主体确定边界。
- 拆分:让非核心生命周期独立出来。
- 内聚:确立各自生命周期及其主体,活动结果累积在主体上。
- 沟通:核心与非核心生命周期之间设立沟通机制。
【三】
架构本身也有生命周期。
架构可以拆分为2个子生命周期:架构设计生命周期、架构实施生命周期。
架构设计生命周期,为实施生命周期服务。前者为非核心,后者为核心。(架构只有设计方案是没有意义的,最重要的是把架构落地执行。)
【四】
概念:人们把解决问题的解决方案,给定了一个名字,这个名字就是对应的某个特定的概念。
【五】
正确的认识概念,发现概念背后所代表的问题,找出核心生命周期。
认识目标领域所需要解决的问题、核心生命周期,这是做好架构的基础。
4. 抽象
【一】
当两个概念背后实际解决的问题不一样时,个性是完全不一样的,所以不能用抽象来定义一个事物。
抽象实际上是一个分类的过程,人们抽取出事物中自己所关心的一些特征,不同的人抽取的侧重点不一样,甚至完全不同。
【二】
做架构的人,必须亲自体验业务、感受业务,才能真正认识业务的个性,真正认识业务所面临的问题。
在理解业务个性的基础上,才能谈共性。否则,这个抽象局限于个人主观,难于长大。
5. 识别问题
【零】
识别出要解决的问题,找出核心生命周期,问题就已经解决了八成。
识别问题,这个能力基本上就决定了架构师的水平!
【一】
“一位女士对老公说:把袋子里的土豆削一半下锅。结果所有土豆都下锅了,并且锅里煮的每个土豆都被削了一半皮。”
——这个老公十有八九是程序猿 -_-||
【二】
接到任务,要问的第一个问题:目标问题是谁的问题?——明白了问题的主体,才能真正认识问题是什么。
在上面的故事中:
正确 | 错误 | |
---|---|---|
问题 | 晚饭要吃土豆 | 一个必须完成的任务 |
问题主体 | 家人 | 自己 |
边界(约束) | 土豆是要吃的,给人吃的,给家人吃的 | |
其他问题 | 如何煮,是否放高压锅煮,放多少水,煮多长时间,…… |
【三】
处理问题时,如果发现自己专注于把自己的工作完成,要马上警惕起来!
这样下去,会变成没有主人翁精神(Ownership),不求甚解,从而无法真正理解。
【四】
任何找上架构师的问题,绝对都不是真正的问题。——如果是真正的问题,提问者自己都解决了,不需要找架构师。
架构师都要有这个自觉:发现问题永远比解决问题更加重要。
【五】
无法定位问题时,尽量隔离问题影响范围,争取更多时间、空间去识别真正的问题。
6. 拆分
【零】
拆分就是对相关人的利益进行调整。
【一】
原则:
- 被拆分的生命周期,如果需要主体在连续时间内持续执行、且不能被打断并更换主体,就不能拆分。
- 每个生命周期负责人,对负责的生命周期是“权责对等”的。
- 拆分出来的非核心生命周期,不应该超出核心生命周期主体的负载。
- 拆分是内部活动,对整个系统的外部应该是透明的。
【二】
基于 “权责对等(原则2)”,架构拆分应该形成“树状”的结果。不应该变成有向图,更不应该是无向图。
谈架构,就是谈分层,没有错。但要知道层的背后是树,如果只用层的方式处理,最终会破坏树的结构,得不偿失。
- 例如:如果一个组织架构出现了“图”,比如多线汇报,一定是对利益相关人的利益分析出现了问题,必定会导致权责不对等的问题发生。这个问题持续越久,组织运作效率越低,对利益相关人、组织的利益是越不利。
- 同样,权责对等、高内聚、低耦合,对服务化软件架构,也有重要的意义。
【三】
拆分的过程,就是“建模”的过程,每个生命周期都是一个模型。
拆分出的不同子生命周期,形成了不同的“概念”,每个概念背后就是一个生命周期。
核心生命周期模型,把所有的模型,通过树,组织起来,形成一个新的模型。
7. 流程
【一】
一个流程的执行过程,本质上是一个生命周期,但不是一个事物的简单的生灭。
流程,是描述整个事物发展各种可能性的“树”。
人们看一颗树,总是注意到丰富多彩的树枝、树叶、花朵,而往往看不到更重要的树干、树根。要知道,树干树根结实了,自然生出好看的花朵。
同理,人们往往被流程的分支迷惑,忘记了流程背后的实质,也即核心生命周期。
8. 架构师
【零】
架构的目的就是为了增长。
【一】
人人都是架构师——每个人,当思考如何做的更多、更好时,必然会去拆分自己的核心生命周期和非核心生命周期,人人都具备做架构师的能力。
【二】
做:
- 第一目标:增长。
- 第一思考:发现核心生命周期,确定核心生命周期的主体。
- 剥离出非核心生命周期,确保合理分配非核心生命周期的权责。
- 根据生命周期运营情况,对未来预判,做战略架构。
【三】
评:
- 根据问题的解决效果,也就是增长的效果来决定。
- 很少的资源,达到了很大的业务增长,就是一个好的架构师。
需求
需求的架构:策划需求工作如何开展。
需求模型分四类(OPSD),从四个视角对需求进行分析和描述。
O:Object 目标模型
主要用于描述系统的业务价值,并且根据系统的价值设置功能和需求的优先级。
它比较特别的地方在于,将功能与业务目标联系起来。
通过建模,理清为什么要做这个功能,是要实现什么目标,带来什么价值……
目标模型包括:业务目标模型、目标链、关键绩效指标模型、特性树、需求映射矩阵。
目标模型的主要思路是:通过业务目标模型进行业务问题分析,为了解决这个问题,我们想要达成的目标是什么。
P:People 人员模型
主要用于描述干系人以及他们的业务流程和目的。
我们常见的组织结构图(Org Chart)就可以归为其中的一个模型。
在建立流程模型时,我需要对照着Org Chart进行检查,有没有角色和人员的遗漏。
在编写用例时,通过OrgChart和流程,相互检查是否有过度的设计或者遗漏。
S:System 系统模型
描述存在什么系统,用户界面是怎样的,如何交互,如何响应。
D:Data 数据模型
从最终用户的角度,描述业务数据对象之间的关系。
注意,不是数据库设计,而是从最终用户,从业务的角度进行分析。
干系人想要用数据来做什么,数据是怎么传递和计算的。
干系人关心的数据方面的信息,通过这个模型进行分析、展示和说明。
软件架构
1. 前言
【一】
需求开发只占用了一小部分时间,而设计关系型数据库的结构,设计认证、授权和报告,设计应用签名和令牌,设计REST风格的URL结构,开发API调试工具,编写API文档,这些事情却耗费了大量时间。花了这么多时间做这些事情,并没有增加任何功能,又感觉不能不做,这到底是为什么? 对这个问题的思考和学习,就是对软件架构的入门。
【二】
看到了离岸外包可以节省成本,结果往往是本地开发者被推向所谓“高价值”的软件架构职位,而编码则交由他人完成。多数情况下这只会让软件架构和开发更加脱节,还常常让人像赶鸭子上架一样不得不去承担架构工作。这些组织也常倾向于把架构师看作一种职位级别,而非工作角色。
【三】
预先设计和演化架构,是可以共存的。
【四】
所有架构都是设计,但并非所有设计都是架构。
架构,反映了使一个系统成型的重要设计决策,而重要性则通过改变的成本来衡量。
从本质上讲:重要决策即“架构”,其他的都是“设计”。
【五】
在我们的系统中,哪些是重要的(或者说“架构的”)?可能包括:
- 系统的形态(例如,C/S、基于web、原生移动客户端、分布式、异步、……)
- 系统的结构(例如,组件、层、交互、……)
- 技术选型(例如,编程语言、部署平台、……)
- 框架选型(例如,WebMVC框架、ORM框架、……)
- 设计方法/模式(例如,针对性能、可伸缩性、可用性等的方法)
技术选择=风险管理:测试你的架构,主动发现、减轻和承担高优先级的技术风险。
【六】
经验是一个好的评价标准,但需要看的更深:
- 架构驱动力:捕捉和挑战一套复杂的非功能需求,还是简单的假设它们的存在?
- 设计软件:从零开始设计,还是扩展已有的?
- 技术风险:证明你的架构能够工作,还是盲目乐观?
- 架构演化:持续参与和演化你的架构,还是把它交给“实现团队”?
- 编写代码:参与交付的实践部分,还是袖手旁观?
- 质量保证:保证质量并选择标准,还是反其道行之或无所作为?
【七】
软技能,是必要的。
2. 生命周期
【零】
两个子生命周期:开发生命周期、运行生命周期。
【一】
人们真正需要的是软件启动后为我们带来的服务,也就是说软件的运行生命周期,才是人们真正需要软件的地方。
【二】
软件开发的架构:围绕其核心生命周期进行切分,把可以并行的非核心生命周期切分出来,提升不同人员工作的时间、空间的并行度,从而达到增长的目标。(注意:这里的软件开发架构,也指软件开发工作的模式,与软件(系统)架构的概念不同。)
3. 定义
【一】
解决两个问题:业务的问题、计算机的问题。
业务问题的主体:业务Owner。
计算机问题的主体:软件工程师。
【二】
简单的增加软件工程师,并不能有效的提高产出。
如果业务生命周期只有一个,对业务的理解,不是增加人手就可以解决的。
只有分析业务的生命周期,通过拆分才能提升并行度。
【三】
代码的架构:
- 切分/分层:
- 分层方式:前端代码、业务代码、存储代码等等。
- 分层的原则:根据用户对软件访问的生命周期,识别出核心生命周期、非核心生命周期,形成树状架构。
- 分层,不能破坏树的结构,有树才有分层,有分层却不一定有树。
- 业务模型:体现在代码中的,和现实生活保持一致的,虚拟化的业务及组织架构。
【四】
部署的架构:
软件部署的机器,也会根据用户访问的生命周期,按照树状的结构拆分,所形成的是,硬件部署树状架构、软件部署树状架构。
【五】
软件架构,离不开软件开发团队的组织架构,因为架构的核心生命周期,就是架构的执行。(PaaS平台,是一种虚拟化的开发组织架构。)
【六】
业务相当于基因,架构树状拆分则相当于细胞分裂。
4. 软件架构师
【零】
其他行业,比如建筑架构师,主要处理的是本行业的问题。
而软件行业,通常是在解决其他行业的问题,以业务问题是否解决为判断标准,提高了对软件架构师的要求。
架构师要看清楚,需要解决问题的主体,是业务人员,不是自己。
【一】
业务:为业务服务,而不是主导业务。无法直接调整业务利益,只能够某种程度的去影响。
软件:对于开发、运行生命周期,要具备权力去调整。
【二】
架构师的核心在于架构的执行。
软件开发团队的组织领导人,其实都是架构师,有权力调动这个组织的架构,才能把软件开发、运行生命周期和业务生命周期的拆分落地执行。
软件行业,很多公司设立了架构师的职位,只能建立某些流程,比如强制架构Review、给出架构建议等。通常增加了沟通成本,提高了研发成本,最终导致这些流程流于形式,得不偿失。
(PaaS平台通过标准化、自动化、平台化,让流程的执行落地,是一个高效方法。)
【三】
深入理解技术背后的驱动力,了解技术是如何实现的,从而做出更合适的技术判断和选择,这就是所谓的“接地气”。
【四】
业务、架构和技术三者的关系:
- 业务是核心,技术是解决业务问题的工具,而架构是让业务长大的组织方法。
- 架构需要用技术来实现拆分,而技术需要架构来合理组织。
【五】
一个好的软件工程师组织架构,与软件、组件进行对应,与业务的组织架构对应。
——架构师成为了软件开发生命周期推进的组织角色,为软件工程师们保驾护航。
【六】
架构师需要项目经理来协助搜集每个项目,也就是每个迭代的进行状况,对不同项目做不同调整。
【七】
软件开发生命周期,本身就是一个比较复杂的业务,自身也需要软件来进行虚拟化。
- 比如需求管理、项目管理、代码管理、测试构建部署管理,等等,把核心生命周期精简,拆分非核心生命周期,用软件来实现自动化,让软件工程师专注于写代码,提升效率。(这也是PaaS的意义)
- 为了减轻软件工程师负担,要把软件开发过程中的非核心生命周期,拆分出来,形成软件开发本身的业务架构,并通过自动化,来提升软件工程师的开发效率。
【八】
软件架构师,首先必须是业务的架构专家,同时还得是软件的架构专家。
可以根据核心生命周期,把非核心生命周期拆分出去,形成不同领域的架构师。
【九】
职责:
- 理解业务组织架构,对业务生命周期拆分。
- 对软件开发生命周期拆分,建立软件开发本身的业务架构。
- 基于以上2点,建立软件开发团队的组织架构。
- 对软件进行架构拆分,匹配业务架构与软件开发的架构。
5. 架构的拆分
【零】
从软件团队到人,从人到组件,形成的是一棵树。软件和组件,组件和组件之间,形成的也是一棵树。
【一】
最好的情况是,一个业务团队对应一个软件开发团队。让开发团队的组织架构树,与业务团队的组织架构树是匹配的。
6. 代码
【零】
讨论架构时总是提起“内聚”:
- 内聚,就是要确保一个事物的生命周期是完整的,而不是分裂的。一个生命周期的主体,从生到灭之间的整个过程中,所发生的行为、状态,是累积在一个主体上的。
- 如果生命周期中,某些行为、状态累积到了其他的生命周期主体上,就不是内聚的,不内聚就会导致权责不对等。
【一】
不同用户的访问通道,一定要隔离,不能重用,不能互相影响。
【二】
一种标准的服务代码架构:
- 服务调用并组合业务逻辑,完成业务访问,是核心生命周期。
- 服务:专注于用户需求。作为通道,把粘合代码和用户联系起来,成为了业务虚拟人和用户的桥梁。
- 粘合代码:专注于管理业务生命周期。业务逻辑属于行为,是没有记忆的,而存储属于记忆,是没有逻辑的。把行为和记忆粘合在一起,模拟了一个虚拟的人。
- 业务:专注于实现业务的生命周期活动。
- 存储:专注于数据的保存和加载。
【三】
- 服务:代码特点是简单的顺序调用,不需要单元测试,保证连通性即可。不同服务之间保持隔离,不考虑代码重用。
- 业务代码:代码需要重用,必须保证测试覆盖率100%,业务问题可以通过单元测试快速发现。业务模型里的每个对象,是围绕核心生命周期,展开的一个树状架构。
- 服务、粘合、存储代码变得简单了,能投入更多时间研究业务。
- 服务多,不是问题,服务的生命周期管理才是问题。服务治理中心,就是来解决这个问题的。
7. 测试
每天能够看到自己的单元测试运行结果全是绿色,或者正在逐渐把红色的变为绿色,岂不是很有成就感?何必在焦虑中,等到一周后的测试人员反馈?
8. 设计模式
【零】
软件设计模式,是一个架构拆分的结果,只是这个拆分被标准化了,可以被重复使用。
【一】
- 粘合代码:是为了给业务对象加上状态,可以用“装饰器(Decorator)”模式。
- 服务:扮演的是“代理(Proxy)”模式。
- 存储:基本上就是“适配器(Adapter)”模式。
9. 运维
10. 访问
【零】
访问路径(早期):用户->目标软件->硬件。
访问路径(现在):用户->客户端->网络->目标软件->应用服务器->容器->操作系统->硬件。
访问路径上的业务,是计算机和软件自身的业务,是为降低软件的开发难度,沿着访问生命周期,做架构拆分而形成的。
【一】
集群:
- 用户的访问路径又一次架构拆分,增加了访问路由,负责把用户请求按规则转发到集群内某一台机器。
- 集群路由还负责检查集群内机器的健康和剩余访问量。
- 同一个集群的不同机器之间,要做到能够共享用户的状态,让集群对用户透明。
【二】
数据中心:
- 集群像是一个城市,数据中心则像是一个国家,分布在全世界,让用户就近访问。
- 与集群路由不同,数据中心路由,是将所在地的用户访问归属到相应的数据中心。
- 多个数据中心的不同集群资源,称为池。集群是物理的,池是逻辑上的集群。
文章作者 JF
上次更新 2018-03-22