互联网创业公司架构 公司架构

专注Java领域的优质技术号 , 欢迎关注
原文:张慧清CSDN
作者简介:张慧清 , 10多年的IT老手 , 系统分析师和项目管理部门 。曾任中国青年易行CTO、桐城交通创新科技负责人、古达集团总建筑师、携程建筑师 , 带领30-200人的技术团队 , 将R&D能力提升1-2个档次 。现在我们注重建筑设计和工程的效率、技术的实现和中小型R&D团队能力的提高 。
你做过建筑设计吗?你认为我们应该做建筑设计吗?你们公司做过什么建筑设计吗?互联网公司的架构怎么设计?
不知道你怎么想的 。在我得到的回复中 , 大部分人都认为应该做建筑设计 , 但是很少自己去做 , 经历过的公司也很少做建筑设计 。
这里有一个矛盾 。大多数人和公司都会犯错吗?
我不这么认为 。专职建筑师越来越少 , 大部分建筑系解散 。为什么会这样 , 怎么办?
初识架构设计
软件工程一般可以分为需求、设计、编码、测试、部署和维护 。既然架构设计是一个过程 , 就有输入和输出 。PRD产品规格输入架构设计 , 架构设计文档输出 , 中间是处理程序和工具 , 如下:
输入:功能性需求和非功能性需求 , 从PRD中选取;流程和工具:1 。设计目标和想法
2.功能设计:用例视图和用例活动图
3.应用:边界、逻辑架构、接口和域图
4.数据存储
5.物理架构、安装和部署
6.非功能性设计
输出:设计说明 , Word、Visio、UML等表达工具 。需求是我想要的 , 建筑设计是我怎么做的 。架构设计为施工阶段提供指导 , 有利于后续的编码、测试、部署和维护 , 包括项目调度、人员划分、协调、单元测试、物理部署、系统修改和升级 。设计是施工计划 , 没有设计就没有管理 , 计划可以节约施工成本和时间 。如果没有架构设计 , 就开始写代码
> , 会导致很多的问题 , 干着干着就干不下去了 , 或干到一半必须得改等等现象 。


应用架构设计案例

以下是一个真实的应用架构设计案例 , 《国内航班查询引擎项目》的架构设计过程如下:
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 设计表述探讨
  1. 一定要有架构设计文档吗?按教科书是需要的 , 但真实的情况可能并不是这样 , 没有设计文档的情况并不少见 。
  2. 架构设计文档要不要保存?项目做完后 , 它要保存多久呢?你待过的公司有保存吗?我们要沉下心来问问自己 , 追求真实比书本更为重要 。
  3. 设计文档到底在为谁服务?为自己还是为别人?为半年后的自己 , 还是为公司或同事?
  4. 设计可以省掉吗?在没有设计文档的前提下 , 是否可以编写高质量的代码?如果文档可以省掉 , 那么架构设计过程呢?
架构设计文档的编写并不简单 , 可能要花一周或一个月的时间 , 成本较高 。设计表述方式有多种 , 具体如下:
  • 架构设计文档:它相当于造房子用的施工图纸 , 是相对比较正式的方式;
  • 需求分析设计或项目排期会议:PRD出来后 , 研发成员一起开需求分析设计会 , 分析讨论的过程也是设计的过程 。或者通过项目排期 , 在估算项目难易程度和排期时 , 也有设计分析的成分;
  • 设计邮件:一份简单的设计邮件 , 内容大约有:问题描述、原因分析、技术方案、架构建议等;
  • 非正式讨论:几个人站在白板前 , 讨论和画画 , 会议结束后再把它拍下发给参与人员 。
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具体如下:
  • 单一职责原则SRP:一个类只做一种类型的责任 , 一次只做一件事;
  • 开闭原则OCP:对扩展开放 , 对修改关闭 。开闭原则具有理想主义的色彩 , 它是面向对象设计的终极目标;
  • 里氏代换原则LSP:任何基类可以出现的地方 , 子类一定可以出现 , 它是一个建议或约定;
  • 接口隔离原则ISP:不能强迫用户去依赖那些他们不使用的接口;
  • 依赖倒置原则DIP:高层模块不应该依赖低层模块 , 但它们都应该依赖抽象 , 客户第一 。
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 要不要做架构设计
哪些项目需要做架构设计呢?越大的项目越需要做架构设计 , 开发时间越长的项目越需要做架构设计 , 参与人员越多、内部越复杂、外部依赖越多、影响面越大、维护成本越高的项目越需要做架构设计 。那互联网的项目呢?它有以下特征:
  • 时间:开发的周期整体很长 , 可能维护10年、20年 , 但单个应用的开发周期短 , 多半以天和周为单位;
  • 规模:互联网项目整体很大 , 但单个应用规模小 , 会被拆分为多个小应用;
  • 业务知识:为自己做系统 , 行业知识不缺 , 长期为一个系统服务 , 有些自己也是客户;
  • 复杂度:研发人员多 , 内部关系复杂 , 外部依赖多 , 变化大迭代快 , 在不断地演化 , 24小时不间断运行 。
4.2 MVP与架构设计



互联网创业公司架构 公司架构

文章插图


MVP的英文全称是Minimum Viable Product , 是最小可行性产品的意思 。
如上图所示 , 用户需要一个交通工具 , 有两种实现方式 , 第一种做法是分多个阶段设计与制造 , 第一步是造一个轮子 , 第二步是造两个轮子 , 第三步是造一个盖子 , 第四步是一辆可用的轿车 。
第二种做法是每一阶段都要满足用户从A地到B地的需求 , 第一步先造个滑板 , 第二步是造个自行车 , 第三步是造辆摩托车 , 第四步是造辆轿车 。第一个版本到第三个版本输出的产品都可以满足用户的基本需求 , 虽不完善但可以解决用户的问题 , 并且越来越好 , 到了第四个版本的产品才是客户预期 。
MVP对架构设计提出更高的要求 。如果单纯从研发内部的角度 , 第一种是施工成本较低的方案 , 但我们需要以客户为中心 , 需要不断地满足客户的需求 , 所以在做设计时 , 不仅要考虑施工的成本 , 还有客户需求、扩展性、继承性等 , 如上图第三种设计方案 。
4.3 互联网公司是怎么做的
互联网公司的架构设计是怎么做的 , 当前主流做法有:
  • 分工:将技术研发和业务研发相分离 , 下层是云平台部或基础架构部 , 提供IaaS、PaaS中间件等云服务 , 上层是各业务线的产品研发部 , 专注于业务场景的应用研发;
  • 敏捷:业务研发敏捷化 , 产品与研发、测试实时沟通 , 以减少行业知识的缺乏;
  • 整体:技术委员会 , 负责技术总体规划和技术成长;
  • 未来:研究院 , 解决未来的技术问题 , 如阿里达摩院、百度研究院;
  • 应用架构:主要负责技术与业务的结合 , 由应用架构师、技术经理或高级程序员担当 。
4.4 应用架构要怎么落地
应用的架构设计要怎么落地 , 常见如下:
  • 总体架构规划:手握地图 , 才能明确自己所处的位置 , 以便于配合 。总体架构规划可以让每个研发人员了解整体 , 它如同房子的地基框架图纸 , 可长期保存和更新维护 。具体参考TOGAF开放组体系结构 。
  • 单个项目架构设计:重点项目一定要做架构设计 , 参与架构评审 , 非重点项目可简化设计表述 。
  • 应用架构评审:以流程的方式来保证应用架构设计的质量 , 例如重构项目、跨部门项目、业务核心项目需要经过应用架构评审之后 , 才能申请服务器、数据库、域名等 。
  • 其它工作:如果有应用架构师专职人员 , 除以上工作外 , 还包括统一公司应用分层、制定代码规范、组织技术培训、中间件推广、应用性能调优等 。
AppArchDemo案例参考地址:
https://github.com/das2017/AppArchDemo