需求分析
需求分析:理解与挖掘用户的诉求,以及背后的逻辑,转换成可行性的分析结果。从非结构化到结构化,确定系统的职责、模块的过程
一切系统从用户真正的诉求出发
需求分析关注点:
需求边界:将需求确定到一定范围
用户故事:用户角色的用户故事
乘客的故事,发生场景是什么?
用户路径:跟系统的触点
用户的意图是什么?用户路径尽可能的短,降低用户使用成本
1、诉求背后的人性
人性是提出需求的本源
2、需求产品化
模块化、配置化、有逻辑
3、需求落地路径
需求分析 -> 可行性 -> 设计 -> 编码 -> 测试 -> 发布
两种头疼的需求:
导致产品没人用,解决不了用户问题
伪需求:没有调研、没有目标、没有逻辑的无脑需求
应对:
1、用数据化结果否认需求合理性
熟悉数据,用数据说话。针对调研结果:用户分层是什么、用户是否赞同
PMF(产品/ 市场契合点):产品和市场达到最佳的契合点,提供的产品正好满足市场的需求,令客户满意。
没有该产品会令用户遗憾吗?
2、用正反案例来说明需求需要改进的地方
历史教训,正反例
3、用户路径和触点推演需求合理性
推演用户如何操作,是否合理
权力需求:老板或强势业务方的需求
1、先肯定需求价值再提出需求实现的成本
2、给出更好的需求替代方案(PLAN B)
3、从数据和案例角度说明快速上线的危害性
问题的分层
(本源问题)用户问题:用户想做什么
(经营视角)业务问题:支持一切的可能的方式
(体系结构)产品问题:考虑逆向流程、异常流程… 需要制定体系化、人性化、有产品逻辑的解决方案
(架构代码)技术问题:高并发、可用性,实现解决方案的链路。技术问题可能会否定用户问题。
开会时要明确具体讨论的是哪一层的问题,谈用户问题的时候不要谈技术。
KISS原则
Keep It Simple and Smile
Simple: 架构的理念是大道至简:解决问题
- 如何令系统有 可扩展性和可维护性
- 如何令系统能 恰到好处地解决问题
- 如何令系统能 运行 3-5 年不重构
重构必然发生,要小步快跑地重构
Smile:现代软件需要很强的协调能力,保持微笑,迎接各种否定
- 业务部门的挑战(价值问题)
- 成本部门的挑战(ROI问题,ROI:投入产出比)
- 测试部门的挑战(可测试性)
- 技术部门的挑战(可行性和工期)
DRY原则
Don`t Repeat Yourself:一切重复的代码都可以抽象
重复代码的危害性
不一致性 、代码冗余 、易出BUG
七大设计原则
共同点:提升软件的可扩展性、可维护性,是抽象思维和归纳思维的集中体现
实践点:类图设计、接口设计、组合设计
单一职责原则
牢记类定义的初衷
1、最简单,却又最难
2、高内聚、低耦合的延伸
3、属性和行为向着模块预先定义的功能内聚
4、模块名字非常重要
违反该原则,导致代码难维护、难扩展。不能从类名中看出有该功能,人会遗忘
里氏替换原则
父类能够出现的地方,子类一定能够出现;而子类出现的地方,用父类去代替,一般都有问题
正例:能够继承:勿带食物可以代替勿带饼干、勿带面包
反例:不能继承:似是而非的继承关系,不是一个属性。蛋跟笨蛋,饼跟铁饼
接口隔离原则
接口的粒度尽可能的小,统一接口的方法强内聚于同一特征
组合复用原则
组合是一种松散的合作关系,组合产生的对象,方法暴露的少
继承是一种绑定关系,相当于父子关系
组合是一种松散的合作关系,相当于短期同事关系
组合产生的对象,方法暴露的少
继承产生的对象,继承路线上的方法全部暴露出来(接口污染),增加用户的选择成本,容易误用
在里氏代换基础上,组合复用的目的使我们的代码尽可能的暴露与本类相关的行为,避免接口污染
依赖倒置原则
细节依赖抽象,底层依赖于高层
迪米特原则 / 最少认知原则
最少认知原则。相互了解的信息,尽可能的少。
使用接口只需了解输入输出即可,不需要关注具体代码实现
开闭原则
对扩展开放,对修改关闭。
扩展能力主要是对需求继续变化的适应能力
代码最大的稳定性,一旦成功运行,就不应该改具体的代码
通过依赖倒置,实现增加类,或者模块的方式,实现需求的变化。
任何变化的点,都是需要被隔离出来的。
架构师最大的难点:识别和隔离变化点
熵增定律
熵:反映自发过程不可逆性的物质状态指标,熵是衡量我们这个世界事物混乱程度的一个重要指标。一个孤立系统总是存在从有序转变成无序的趋势,这就是熵增定律。
熵增是我们宇宙中最绝望的定律,有什么办法抑制混乱程度的加剧?
开闭原则是熵减
对抗熵增的最好方式是熵减。熵减最重要的是形成开放性;
开放性设计是系统能够有序接纳外部能量的能力。
在软件领域,我们的外部能量指的是需求的多变和业务的不断试错
扩展性设计是一种开闭原则的思维
做向未来扩展的预测
单一职责原则:职责是否具有唯一性,一个类仅有一个引发变化的原因
正例:高内聚、低耦合的延伸,属性和行为向着模块预先定义的功能内聚
开闭原则:设计或修改程序代码时,仅扩展而不修改原有程序。
正例:使用各种不同的工具和框架,不可能做到所有工具的自行开发,
通过开闭原则就能进行很多的扩展与改进,不需要重复造轮子
里氏替换原则:子类能完全替换基类。
正例:使用不同算法的代码替换同一接口的功能
接口隔离原则:不强迫用户依赖其不用的方法
反例:接口中有多余的定义,会强迫实现接口中的低频方法
依赖反转原则:
1. 高层模块不应该依赖底层模块,二者都应该依赖于抽象;
2. 抽象不应该依赖于细节,细节应该依赖于抽象。
正例:通过寻找好的抽象来解决大量重复工作的效率问题
迪米特原则/最少认知原则:
1. 一个类只应该与它直接相关的类通信;
2. 每一个类应该知道自己需要的最少知识
正例:分层架构中,每一层的模块只能调用自己层中的模块
组合复用原则:尽量使用对象组合,而不是继承来达到复用的目的。
在新对象里使用已有对象,使之成为新对象的一部分:新的对象通过向这些对象的委派达到复用已有功能的目的
正例:业务层Service的注入
架构与架构图
架构是一种能力、而不是一种职位
解决问题是关键
架构 = 组成 + 决策
组成 = 模块结构 + 模块关系
决策 = 约束 + 设计原则 + 演化方向
架构设计的目的
1、确定系统边界(在技术层面上做与不做);
2、确定各个模块之间的依赖关系(模块的宏观输入与输出);
3、确定后续的子系统或模块设计的演进方向(在一个既定的框架内和技术方向上);
4、确定非功能性需求(安全性、可用性、可扩展性等)。
如何画架构图
架构图是 水平业务模块 + 垂直技术模块 依赖形成的 逻辑结构图
一、搞清楚要画的架构图的类型(业务、技术、数据)
二、确认架构图中的关键要素(产品、技术、服务)
三、梳理关键要素之间的关联:包含、支撑、同级并列等
四、输出关联关系清晰的架构图
如何判断架构图的好坏
布局:图形的上线左右前后6个方向的位置关系
颜色:视觉中心在哪里,哪些元素被忽略
逻辑:组件之间的依赖,业务实现的可行性
二维图形的前后:上层模块依赖下层模块
架构图的分类
业务架构:使用一套方法论,对所涉及到的业务单元进行边界划分。熟悉业务
应用架构:对整个系统的实现进行可视化落地实现,系统的层次/开发原则/各个层次的应用服务,一般为垂直依赖型
数据架构:是一套对存储数据的架构逻辑,根据各个系统应用场景、不同时段的应用场景,对数据进行诸如数据异构,读写分离、缓存使用、分布式数据策略等划分。
思考:系统需要什么样的数据?如何存储这些数据?如何进行数据架构设计
技术架构:承接应用架构的技术需求,并根据识别的技术需求,进行技术选型,把各个关键技术和技术之间的关系描述清楚。
传统架构图:4+1
物理视图:和部署相关的架构决策(一般不画)
逻辑视图:设计满足功能需求的架构(逻辑结构图)
开发视图:设计满足开发期质量属性的架构(UML图)
处理视图:设计满足运行期质量属性的架构(UML图)
场景视图:需求分析技术,通常采用UML的用例图进行设计
UML统一建模语言
使用图形和符合描述软件模型中的各个元素和他们之间的关系
分类:
静态结构图:类图、对象图、包图、组件图、部署图
动态行为图:交互图(时序图和协作图)、状态图、活动图
类的六大关系:
泛化关系:即继承关系
实现关系:实现接口
聚合关系:业务上整体与部分可以分开,是关联关系的特例
组合关系:业务上整体与部分不可以分开,是关联关系的特例
依赖关系:只要在类中用到了对方,就存在依赖关系
关联关系:体现的是业务逻辑的关系,是依赖关系的特例,具有导航性&多重性
组合跟聚合,组合更强
聚合:鼠标跟电脑,聚合的UML表示:虚心菱形 加实线
有聚就能有散,鼠标不舒服可以换,电脑还存在,鼠标也可以接在其他显示器
组合:大脑跟头,组合的UML表示:实心菱形 加实线
大脑跟头是组合,二者不能单独存在
聚合生命周期可以不一致,可以单独存在
组合生命周期一致,不能单独存在
时序图:
通过描述对象之间发送消息的时间顺序显示多个对象之间的动态协作。
关注正常流程,不关注逆流程,不关注异常流程,不关注分支判断
架构图:
定义:表达架构集合的载体,是水平的业务单元 + 垂直的技术单元 组成的 逻辑结构图。
作用:将目标系统的结构可视化,通过直观的方式描述技术思维,减少沟通障碍,提升协作效率划分目标系统的边界。
模块五、23种设计模式
5种创建类:
单例模式、建造者模式、抽象工厂模式、工厂方法模式、原型模式
7种结构类:
代理模式、装饰模式、适配器模式、桥接模式、组合模式、外观模式、享元模式
11种行为类:
访问者模式、模板方法模式、策略模式、状态模式、观察者模式、备忘录模式
中介者模式、迭代器模式、解释器模式、命令模式、责任链模式
小结
架构 = 组成 + 决策
架构四个目的:
1、解决系统边界
2、解决模块间关系
3、指导后续演化原则
4、解决非功能性需求
架构是种能力而非职位,架构的理念是大道至简——解决问题
架构图:水平方向的业务单元 + 垂直方向的技术依赖形成的逻辑结构图,传统的架构图是 4 + 1图
设计原则:迪米特/最少认知原则、里氏替换原则、接口隔离原则、单一职责原则、组合复用原则、开闭原则、依赖反转原则
架构实践:工程结构、架构图、类图、时序图…