搞Java的开发人员交谈中经常提及框架和架构两个词汇。Java开源社区活跃,大量优秀的开源项目可以学习借鉴这,本来是件好事。但同时又难免会让人好高骛远,被空中楼阁所迷惑。
搞Linux下C开发,.Net开发的同行们就很少言必称框架与架构,默默地编码实实在在地做项目。想起刚刚参加工作时候,公司的CTO告诫年轻同事说,“别跟我扯框架,你先写了10万行代码再和我说”。
为什么公司的资深工程师不愿意和年轻的开发工程师谈这些内容呢?因为对架构的理解是有一定的经验门槛的,看不见摸不着的抽象概念,说者难以描述清楚,听着更加难以理解产生共鸣。更何况软件行业铁打的营盘流水的兵,因为国内生存压力大,愿意沉下心去研究技术的人就更少了。
一般来讲,5年的编程实践经验,可以对框架有很好的理解;再加上3年的系统设计实践经验,完全可以独立进行架构设计。可以看到很多架构师招聘广告中,都要求有8~10年的研发经验,是有一定道理的。那种天资聪颖悟性高,一入行就有高人指点,同时又从事大型项目研发的当属少数例外了。
我一直苦于无从着手学起,虽然独立设计做了好几个项目,对于如何进行架构设计心里还是没底,缺少理论方法指导。国外这方面的著作大都洋洋洒洒,高来高去,翻译成中文的就更加晦涩难懂。一直到读了温昱先生写的那本《一线架构师实践指南》 ,受到启蒙有茅塞顿开的感觉。强烈推荐有志于成为架构师的同行,去读下这本实践中总结出来的经验之谈,内容描述深入浅出通俗易懂。
市面上能看到的大都是产品最终的架构图,很少有完整的架构设计文档公开,包括Apache上的开源项目都很少有介绍架构的文档。更不要说在架构设计的过程中,是如何从草图开始一步步演进,成为最终成品的。这种单个案例的深度分析,对我来说是最有学习价值的。
在软件架构设计方面,我本人才刚刚入门,功力太浅,唯有写些自己在实践中的思考琐碎。
1架构到底是什么
Software Architecture,翻译过来叫软件架构,还有的叫软件体系结构,系统架构。软件架构用来描述系统中的一些重大决策,好比一幢大厦的骨干结构。
你说,这不扯淡吗,说了和没说一个样。什么叫重大决策?领导每次都是发表了重要讲话,到底哪一次是不重要的?
好吧,既然讲不清楚这个抽象的概念,我再细化描述下我理解中的架构应该包含的东西:
1) 从逻辑功能划分上描述清楚系统中的各个组件(子系统、功能模块)的作用职责,组件与组件之间的依赖关系,接口方式及参数。
2) 从物理部署上描述清楚每个物理服务器节点上应该部署哪些组件,组件与组件之间的通讯方式,服务器、存储设备与网络环境的参数指标。
3) 开发子工程的划分,子工程的依赖关系。有时还包括具体的技术选型。工作任务的粒度划分应该与团队中的人员素质相匹配,让专业的人做专业的事。
4) 系统中数据的存储方式,写文件还是写数据库,数据的格式定义。是关系型数据库还是其它存储,集中式还是分布式。数据的冗余备份机制。
5) 系统中的运行进程与线程,启动与停止的先后顺序,进程间的通信机制,线程间互斥资源的加锁与同步。
6) 系统在安全性、可用性、伸缩性、可扩展性、高性能方面的考量。
综上,软件架构涵盖的范围很广,难以用一两句话表达清楚。最终就造成给大家的感觉是,架构是很玄妙的东西,好像只可意会不可言传一样。
本文的基本观念是,架构设计是可以清晰表达出来,有效指导开发人员开展设计和编码工作的。好的架构设计应该是可以落地的,是一个不断演进改良的过程。
2可以落地的架构设计
我见过很多项目做完都没有架构设计的过程。一上来就是经典的三层/四层分层架构,数据库模型设计完,然后就直接SSH开发工程原型搭建好,开工编码了,系统所有功能在一个Web里面搞定。
领导:“小王,我们的系统架构设计已经做好了。你着手开始开发吧,确保高质量完成项目,一个月结项。年轻人只要好好干,升职加薪不在话下,当上CEO迎娶白富美指日可待。”
其逻辑架构图大致是这样的:
开发工程师小王拿过这个图一看,这尼玛就是天书啊,还要求一个月完工,心中顿时一万匹草泥马奔腾而过。
你能说这不是架构图吗?是,确实是分层的逻辑架构,还列出了技术框架选型。
问题是,它是放之四海而皆准的一个通用的设计。对小王来说,这个架构设计就是没有落地的设计,迷茫啊迷茫。
再看一个基于HTTP进行消息通信的系统,其逻辑架构图如下:
小王如果拿到这张图,起码可以获得以下信息:
1) 系统整体上分为消息中介、管理控制台和后台服务三个组件。
2) 消息中介服务接收应用系统发来的HTTP请求消息,存储到数据库和消息队列中间件中,并根据业务需要负责对消息进行转发。
3) 管理控制台用于对通信子系统进行配置管理,查询分析。
4) 后台服务用于实现消息重发服务,历史数据清理服务。
小王拿到这个图至少可以做到心中有数,系统的功能模块有哪些,应该划分成几个开发工程,哪些是可以应用开源项目,哪些通用功能可以进行抽取。
如果小王是一个有经验的高级工程师,看了这个图,结合需求文档,直接就可以开始进行领域模型设计,建表,搭建工程开发功能了。每个组件开发完后,做下代码Review确保功能模块都有实现即可。(对高级工程师来说,代码就是最好的设计了)
如果小王是一个中级工程师,则还需要对开发包进行划分,领域模型类设计,包与包之间的接口参数定义,数据格式以及一些关键的类图设计提供。有疑问的地方进行面对面澄清即可。(对中级工程师来说,要先确认关键类图设计了才能开始开发)
如果小王是一个初级开发工程师,则需要开发工程的原型代码,重要的接口类与核心功能类开发完后才能交给他。配合详细的类图设计,时序图以及状态图设计进行辅助指导,开发过程中进行检查与帮助。(对初级工程师来说,要有代码范例可参照,详细的类名方法参数定义,并且提供协助才能开发)
也就是说,架构设计的成果是不是足以指导开发人员进行设计编码,是看项目团队的人员素质的。一般来说,架构设计的粒度比系统概要设计要粗,但有时候也会细化到概要设计和详细设计之间。架构设计应该一直细化到能指导团队开展实际设计开发为止,也就是我上面讲述的观念,架构设计是可以落地的。
甚至有架构师说,代码可以表述出来的架构,才是好架构。水中月梦中花,再唯美也是虚幻的。
3架构师的关键作用
那架构师对项目组有很大的作用吗?
搞管理信息系统的人说,没有用,整天搞一堆看不懂的设计,还浪费我们时间。没有他,我们照样做项目。
搞互联网应用的人说,作用非常大。没有他,我们的项目分分钟歇菜,那些复杂的技术问题只有他能解决。
显然,随着项目的规模变大,复杂性加大,越凸显出架构师的作用。
实际上,即使是一个最简单的管理信息系统,也是包含有架构设计在里面的。麻雀虽小五脏俱全。用户角色权限管理,审计日志记录,MVC框架,ORM框架,缓存设计这些地方都包含有架构设计在里面。
架构师的作用在于衔接业务需求与系统设计,根据现实条件,设计出一个最合适的解决方案。将业务需求转弯为可落地的架构设计,是最大的价值所在。
而如何从业务需求中抽象出功能模块的划分,通用功能的抽取,组件的粒度如何适中,还要考虑现实环境的约束,预留业务发展的空间,如何深入浅出说服对开发人员理解并接纳自己的架构,这些都是很难的。
最困难的不是去学习技术产品,解决高并发海量数据的挑战;而是思维方式的养成。前者有现成的方案可借鉴模仿,后者只能靠经验去感悟。
对我来说,最难的地方是如何高屋建瓴地,站在系统外,以全局的高度看待多个系统生态圈,抽象出一个个业务组件。开发人员如果只能盯着眼前的一亩三分地(模块设计,OOD),就难以养成架构思维。
反过来看,模块设计又是架构设计的基础,没有前期的抽象思维的训练,没有足够的经验,就无法抽象出粒度适中的组件。抽象出的组件不能落地实现,就会被开发人员认为不切实际,没有作用。
成为架构师的前提条件,必须是一个有足够经验基础扎实的程序员。知识面要广泛,见多识广,还要有一定的技术深度,能理解各种技术的原理,适用业务场景,优劣点。同时,架构师往往还肩负着一个项目的技术攻关,客观上要求在承受压力的同时保持足够的韧性。如果没有机会去独立负责一个个项目,是很难从主观上养成架构思维的,动力不足。
也就是说,是实现业务需求的过程中,实践提升了开发人员的抽象能力,最终培养成合格的架构师。从这个角度说,我认为架构师和高级开发工程师只是职务上的叫法不同,做的工作很有可能是相同的。通俗点讲,一个项目里概要设计是由谁主导的,那这个人无形中已经进行了架构设计的思维训练。
4架构思维的培养
那架构设计的抽象思维可不可以培养呢?
我认为是可以通过训练培养出来的。通过对代码重构可以促进对OOD思维的培养。但是架构设计往往不能频繁改动,牵涉面广(如开篇所说架构设计描述的是系统的重大决策),无法像重构的方式进行修改,只能温和地进行改良。
架构设计的过程,应该是不断地演进完成的。经验需要积累,没有经验时只能一个个项目实践来培养经验,同时借鉴其他人的架构设计(很难拿到素材)。如果能有机会和一些资深架构师一起工作交流,相信能事半功倍,早点领悟。
我在做架构设计的初期,喜欢拿个笔在本子上画草图,帮助自己思考,往往涂掉三十页纸才确定出第一个可行的版本(用电脑画图工具会使思维停顿,思考效率降低,手工画图最快捷)。架构图出来后,写文档只是描述细化的过程,有工作量没有难度。当然,以后再遇到类似的业务需求的项目,就可以借鉴之前项目的经验了。
以上就是我在架构设计过程中的一点所思所想,还非常浅薄。
出处:http://www.uml.org.cn/zjjs/201412222.asp