jiangziya 2019-02-16
作者 | 张辉清
责编 | 胡巍巍
你做架构设计了吗?你认为要不要做架构设计?你的公司有没有做架构设计?互联网公司的架构设计又要怎么做?
我不知道你是怎么想的,在我得到的答复中,大部分人认为要做架构设计,但自己却很少做,自己经历的公司也少有做架构设计。
这里是矛盾的,难道大部分人和公司都犯错了吗?
应该不是这样。专职的架构师越来越少,架构部门也大都解散,为什么会是这样,我们该怎么办?
初识架构设计
软件工程一般可分为需求、设计、编码、测试、部署、维护。既然架构设计是一个过程,那么就有输入和输出。架构设计输入的是PRD产品说明书,输出的是架构设计文档,中间是处理过程和工具,具体如下:
1.设计的目标和思路
2.功能设计:用例视图、用例活动图
3.应用:边界、逻辑架构、接口、领域图
4.数据存储
5.物理架构、安装部署
6.非功能设计
需求是我要什么即What,而架构设计是我要怎么做即How。架构设计为施工阶段提供了指导,有利于接下来的编码、测试、部署和维护,包括项目排期、人员分工、配合、单元测试、物理部署、系统修改和升级。设计是施工的计划,没有计划就没有管理,计划可节约施工的成本和时间。如果没有架构设计就开始写代码,会导致很多的问题,干着干着就干不下去了,或干到一半必须得改等等现象。
应用架构设计案例
以下是一个真实的应用架构设计案例,《国内航班查询引擎项目》的架构设计过程如下:
2.1 功能清单
产品经理提供的PRD文档做得怎么样,第一眼就看它有没有功能清单。下图的功能清单表格主要有两个核心功能,一个是查询航班数据模块,另一个是清理缓存模块。
2.2 用例图与用例活动图
上图是用例图和用例活动图,用例图有查询航班数据和清理缓存,这与功能清单有对应关系。每一个用例都可以展开为用例活动图,产品经理的活动图关注的是业务的逻辑,我们的用例活动图关注是程序的业务逻辑,有更多的技术视角。如图所示,前台网站或Mobile发起查询请求后,经过参数验证,然后分别获取政策、获取贴点、获取价格、获取航班数据,再合并计算数据,最后构建返回数据。
2.3 领域图
上图是领域图,它从用例活动图演化而来,图中的行为与活动图有对应关系。如图所示,平台或Mobile触发查询引擎后,然后多线程获取政策数据、贴点数据、价格数据和航班数据,然后进行合并计算。领域图是应用程序的业务逻辑模型,它的每一个框有可能是一个类,也可能是一个类库,或是一个应用、一个子系统,它是可大可小、可伸缩、可扩展的。
2.4 接口设计
什么是接口?接口是契约、连接和交互,它是应用与外部世界的联系者。
有一位资深架构师说过,“我只需要设计好一套接口,让整个业务流转起来,我的工作就做完了,至于怎么实现我可以不知道”,这话有一定道理。
以上契约遵循统一的Request/Response实现模式设计规范。
2.5 分层设计
2.6 代码实现
左上图是第一个版本的代码实现,例如SearchVerify实现验证查询参数、CaculateBusiness实现合并计算、PolicyBusiness实现政策相关逻辑、PriceBusiness实现价格相关逻辑、DiscountBusiness实现贴点相关逻辑、CacheBusiness实现缓存逻辑、UserBusiness实现用户逻辑。右上图是第二个版本,相对第一个版本的实现要复杂些:ValidateBusiness对应验证查询参数、CaculateBusiness对应合并计算、PolicyBusiness对应政策、PriceBusiness对应价格、TiedianBusiness对应贴点、FilterPolicy对应政策过滤。可能你已经发现,不管代码怎么升级改造,只要领域模型没有发生变化,业务模块也就不会发生大的变化。
架构设计会改变编码方式,在架构设计阶段如果做好了领域模型,你就可以在编码施工阶段,先写业务逻辑层再写数据访问层。先定义好业务服务和数据接口定义,再根据数据定义来实现数据访问。这与表驱动的传统方式有所不同。先写数据层再写业务逻辑层,是先写好数据表的增删改查,然后业务逻辑层只是简单地调用一下数据层,便提供给界面层使用。它只是一个简单代理,完全没有发挥业务逻辑层应有的价值。
2.7 其它设计项
除了以上设计项,还有数据库设计、物理架构设计、非功能性设计。数据库设计有E-R图和表设计,物理架构设计有应用集群、应用部署图、域名等,非功能性设计有性能、可用性、伸缩性、扩展性、安全性等。最后是总结和表述,输出一份架构设计文档,详见下图和附档链接。
2.8 演化
以上是架构设计的关键过程,上一环是功能需求,下一环是代码实施,从功能需求到用例图,到用例活动图,到领域图、架构分层和核心代码,以领域模型为中心去构建业务逻辑代码,然后再实现数据库的访问。它们之间环环相扣,做不好领域图可能源自没有做好用例活动图,因为用例活动图是领域图的上一环。从功能到图纸到代码,从代码到图纸到功能,这是一个可演化可追溯的过程。架构设计如同施工图纸,能直接指导工程代码的实施,以及编码施工次序的改变。
更多知识探讨
什么是探讨,什么是培训?培训是我有知识和经验,然后教给大家,我是正确的,大家照着干就可以了。而探讨是我有一个很好的问题,来问大家,来请教大家,以启发你我的思维。接下来,与你一起探讨以下架构知识:
3.1 设计表述探讨
架构设计文档的编写并不简单,可能要花一周或一个月的时间,成本较高。设计表述方式有多种,具体如下:
3.2 关于UML
UML是Unified Modeling Language缩写,又称统一建模语言,是始于1997年一个OMG标准。它是一个支持模型化和软件系统开发的图形化语言,为软件开发的所有阶段提供模型化和可视化支持。它不仅统一了Booch、Rumbaugh和Jacobson的表示方法,而且对其作了进一步的发展,并最终统一为标准建模语言。UML图型主要有用例图、时序图、活动图、类图、状态图、组件图和部署图。
UML是设计表述和建模工具,虽然它的愿景是全生命周期,甚至用UML直接生成可执行软件。实际上这是很难的,不到真正写代码,不可能明确所有细节。当然,UML在设计过程中还是有一定作用的,例如时序图、类图、状态图,这些如果不用UML图来表示而用文字来描述的话,大家很难达成一致理解。
UML是理想建模工具吗?那什么是理想的建模工具呢?船泊业3D建模,在未生产前就在电脑里把整个船构建起来。塑胶建模工具ProE、商品房售楼部的沙盘,在未见实物前就可通过模型知道很多信息。理想建模工具应该是3D的、动态的、简单而形象的。UML只是一种表述你头脑中思想的工具,相对而言你头脑中的思想才重要,所选用的表述工具要根据双方的实际情况,简单清晰、利于沟通才是目的,并不一定就是UML。
3.3 关于设计模式
设计模式是一套被反复使用的、多数人知晓的、经过分类的、代码设计经验的总结。使用设计模式是为了重用代码,让代码更容易被他人理解。
设计模式于己于他于系统都是多赢的,设计模式使代码编制进一步工程化。每种模式都描述了一个不断重复发生的问题,以及该问题的核心解决方案,项目中合理地运用设计模式可以很好地解决很多问题。
GoF的设计模式共有23种,理解意图是运用设计模式的关键,一图胜万言,下面是图解23种设计模式。
设计模式是代码的形状,是代码结构设计的招式,是练功的套路,如同书是人类进步的阶梯。但练功是练功,打架是打架,真正的功夫要在大规模实战中所得。
从设计模式到代码,再从代码重构到设计模式。设计模式不仅是设计出来的,也是重构「长」出来的。虽然重构并非一定会得到与设计模式完全相同的抽象结果,但重构是设计模式的迭代补充。
设计模式如果使用得过早过多或不恰当,会给代码增加不必要的结构复杂度。重构和模式设计的良好结合,使代码更趋于品质和实用。
GoF设计模式是始于1995年的经典,主要解决当时软件的重用性、扩展性和可维护性问题。而在20多年后互联网时代的今天,版本迭代快、可随时在线更新,使用环境、语言和框架都已发生变化,许多模式是否还合时宜?
设计模式在面试的时候用得多,还是在实际开发中用得多?可能每个人答案都不一样,但每个工具都有其适用场景、收益和成本,思考这些有利于我们更好地使用它。
3.4 关于设计原则SOLID
设计原则是设计模式的关键所在,原则和方法是决策的思想指南,设计原则SOLID具体如下:
3.5 关于DDD
DDD是Domain Driven Design的缩写,翻译为领域驱动设计,它的核心是领域模型。什么是模型?装修人员从来没看过你的房子,但看过以下模型后,就能知道你要装修成什么样。
它的价值在于导航、精炼、统一表述。它能够帮助施工方和客户,全方面和多角度地去看待问题,而不是盲人摸象。它是利于沟通、实现、维护和扩展。
什么是领域?
领是领地的意思,域是边界的意思。领域是一个专业科目,是人为的划分,一个领域一个边界一个框,领域会随着规模、角度和时代的变更而发生变化。例如,公司规模很小的时候,没有财务部,一个人既当会计又当出纳。
当公司规模变大一些时,可以一位做会计,一位做出纳,可划分两个领域。当公司规模变得更大的时候,领域又变了,成立财务部,财务部里有N位,每人干的事情都不一样。业务在变,认知在变,领域的划分也要变。领域是主观的,它是对客观世界的阶段性认知。
领域模型处于业务问题与技术解决之间,先将业务对象抽象成领域模型,然后根据领域模型来实现技术对象。从对象到类再到对象,从具体到抽象再到具体,我们对抽象和具体再做进一步引申。
请问,是先有鸡还是先有蛋?
这个问题不好回答,给你一只具体的鸡和一个具体的蛋,你便能知道它们是父子关系、子父关系或没有关系,但是如果给你一只抽象的鸡和一个抽象的蛋,你是不知道它们是什么关系的。
再请问,是先有类还是先有对象?
这个问题也不好回答。
在设计阶段,是先有对象再有类,在编码阶段,是先有类然后再有对象。
整个过程是:架构师在设计阶段根据业务对象抽象出类,然后程序员在编码阶段,先编写类然后再New出一个对象。从对象到类再到对象,从业务问题到领域模型再到技术解决方案,从问题域到领域模型再到代码实施,这是领域驱动的核心所在。
领域驱动设计=从问题域驱动领域模型构建+从领域模型驱动代码实施。
以上是DDD的分层架构,包括仓储层Repository Layer、领域层Domain Layer、应用层Application Layer、表现层Presentation Layer、基础设施层Infrastructure Layer。从仓库中取出原材料,然后流水线将人、材料、工具组织起来,最后输出给表现层。
上图中,领域层不依赖于仓储层,而是仓储层依赖于领域层。这相当于传统三层中业务逻辑层不依赖于数据层,而是数据层依赖于业务逻辑层。
为什么要这样呢?
这是因为上层需要什么下层就提供什么,而不是下层有什么就提供什么,客户第一、按需生产都是这个道理。在技术的具体实现上即依赖倒置DIP,把接口放在上层,然后下层实现,最后使用IoC工具绑定即可。
3.6 设计不足与过度设计
什么是设计不足,什么是过度设计?
不能解决当前问题的就是设计不足;只能解决当前问题的是恰当设计;能解决当前问题,且又能解决未来一段时间问题的是良好设计;能解决当前问题,但面向未来设计过多,且成本较大,预测错误又不能解决未来问题的是过度设计。
我们要追求恰当设计或良好设计,特别是互联网项目,变化大、迭代快,很难预测未来发生的事项。
那什么是好的设计呢?
好的设计是实用的、易于理解的,是谨慎克制的、简单的,是能够落地的、考虑施工成本的。好的设计要解决业务的问题,你的设计再牛逼,但不能解决业务的问题,那么这个设计就是不好的设计。好的设计是谨慎克制的,不能为Show技术或个人意愿而过多使用复杂的技术。好的设计是能够落地的,如果你的设计在落地上出现很多问题,那么就是有问题的设计。
没有人在设计时失败,只有实施时失败。
3.7 架构设计是艺术
以上架构知识非常重要,但并不是知道了这些,就能做好架构设计了。这如同很多人都会画圆和直线,但并不会画画;很多人会使用钉板和菜刀,但并不能做一桌美味的佳肴。
我们探讨一个具体的问题,“能异步的尽量异步”,互联网公司程序员经常说的这句话,是否正确?
首先,程序员喜欢同步还是异步?用户喜欢同步还是异步?程序员为了并发量,会选择异步。用户不要等待,要求系统立即返回,会选择同步。
那么在什么情况下使用同步,什么情况下使用异步呢?有几个考虑因子,第一个是复杂度,同步=异步+轮询/通知,同步相对简单,异步则相对复杂。第二个是可靠度,如果是2/5/8秒概率较大,那么最好选用同步。第三个是用户体验,当使用异步后,用户体验也需要改进,可立即返回给用户一个单号和进度条。第四个是业务成熟度,业务成熟度分萌芽期、发展期、成熟期、衰退期这四个阶段。对于新业务,能同步就同步,当业务变得越来越成熟,访问量越来越大的时候,容易出现高并发量导致用户排队,这时异步是挺好的选择。
在实际问题面前,选择同步还是异步?
要看情况,需经过分析、思考,你需要知道每一种选择的利弊。分析的过程往往比决策更为重要,当你知道了每一种选择的利弊,这时你喜欢就好,因为你只有喜欢了才能把事情办得更好。
你的架构设计=你+架构设计,架构设计是科学,你是主观意识,最后的决策一定包含了你的个性和情感。科学到最后是艺术,架构设计是艺术。
互联网公司的架构设计要怎么落地
互联网公司的架构设计是怎么做的呢?专职的架构师越来越少,架构部门也大都解散,为什么会是这样,我们该怎么办?
4.1 要不要做架构设计
哪些项目需要做架构设计呢?越大的项目越需要做架构设计,开发时间越长的项目越需要做架构设计,参与人员越多、内部越复杂、外部依赖越多、影响面越大、维护成本越高的项目越需要做架构设计。那互联网的项目呢?它有以下特征:
4.2 MVP与架构设计
MVP的英文全称是Minimum Viable Product,是最小可行性产品的意思。
如上图所示,用户需要一个交通工具,有两种实现方式,第一种做法是分多个阶段设计与制造,第一步是造一个轮子,第二步是造两个轮子,第三步是造一个盖子,第四步是一辆可用的轿车。
第二种做法是每一阶段都要满足用户从A地到B地的需求,第一步先造个滑板,第二步是造个自行车,第三步是造辆摩托车,第四步是造辆轿车。第一个版本到第三个版本输出的产品都可以满足用户的基本需求,虽不完善但可以解决用户的问题,并且越来越好,到了第四个版本的产品才是客户预期。
MVP对架构设计提出更高的要求。如果单纯从研发内部的角度,第一种是施工成本较低的方案,但我们需要以客户为中心,需要不断地满足客户的需求,所以在做设计时,不仅要考虑施工的成本,还有客户需求、扩展性、继承性等,如上图第三种设计方案。
4.3 互联网公司是怎么做的
互联网公司的架构设计是怎么做的,当前主流做法有:
4.4 应用架构要怎么落地
应用的架构设计要怎么落地,常见如下:
AppArchDemo案例参考地址:
https://github.com/das2017/AppArchDemo
作者简介:张辉清,10多年IT老兵,系统分析师、项目管理师。前中青易游CTO、同程交通创新技术负责人、古大集团首席架构师、携程架构师,领导过30~200人的技术团队,将研发能力提高1~2个档次。现关注架构设计与工程效率、技术变现、中小研发团队能力提升。
文章广告为微信自动匹配,与本平台无关,如遇假冒伪劣请联系微信进行举报。