第一天架构设计理论
在进行架构设计之前,我们需要对需求进行分析,以实现具体的需求来进行架构的设计工作。
一. 需求分析
需求分析的核心就是理解和挖掘用户的诉求。所以我们可以从以下几个方面来对需求进行刨析。
- 分析需求背后的人性,人性才是提出需求的本源。
- 通过需求的边界、用户故事、用户路径来对需求进行深入的刨析和理解。
- 把需求有逻辑的给实现出来,使其达到产品化,模块化,配置化等
- 最后是需求的落地
- 需求分析->可行性分析->设计->编码->测试->发布
在实际的开发过程中,我们可能会遇到很多很难处理的需求,比如:- 伪需求
未经严格的调研,并且没有目标,没有丝毫逻辑的需求。
对伪需求来说,我们可以从以下几个方面对伪需求进行拒绝或者处理
1) 用数据化的结果来对需求的合理性进行否定。比如调研的数据,进行PMF调研。
2) 用正反案例来说明需求需要改进的地方。
3) 使用用户路径以及触点来推演需求的合理性。
这里有一个新的概念,可以了解一下:
PMF(Product Market Fit):产品和市场达到最佳的契合点,你所提供的产品正好满足市场的需求,是否令客户满意。 - 权力需求
这个应该是大家遇到的比较多的情况,来自老板或者很强势的业务方的需求。
对应措施:
1) 先肯定需求的价值再提出实现需求的成本。
2) 提出更好的解决方案来代替。
3) 从数据和案例的角度来说明需求快速上线的危害,爆出风险。
- 伪需求
二、架构设计几个原则
- KISS原则
keep it simple and smile
其中simple的意思就是,架构是大道至简的,目的就是解决问题。
所以我们要考虑以下几点:
1) 项目的可拓展性和维护性
2) 架构是否恰到好处的解决了问题
3)项目是否3-5年不需要重构(我当前的公司就一直再重构)
其中smile的意思就是,强大的协调能力,保持微笑。
在与各个部门协同合作时,要协调好各个部门的人员。比如业务部门,测试部门等等。 - DRY原则
Don't Repeat Yourself
这个原则大家应该都经常听到,项目开发过程中要将相同的代码给抽离处理,减少重复,冗余的代码。
三、七大设计原则
用户提高项目的可拓展性和可维护性
- 单一原则
一个类只负责一个功能领域的相关职责。特点:高内聚,低耦合 - 里氏替换原则
所有父类能够使用的地方,子类都一定能使用。这里老师举了几个很有意思的例子:
鲨鱼和鱼都是鱼,从鲨鱼能够游泳,我们可以推出来鱼也可以游泳。
但是我们不能从鲨鱼有牙齿推出来鱼也有牙齿。 - 接口隔离原则
接口的设计的粒度一定要小,同一个接口的方法要强内聚于同一个特征。 - 组合复用原则
尽量使用对象组合,而不是用继承来达到复用的目的。要防止“接口污染” - 依赖倒置原则
面向接口编程。上层模块不依赖于底层模块,细节信息依赖于抽象。 - 迪米特原则
接口之间需要关注的信息尽可能的少。使用一个接口,只需要关注他的输入和输出就行。 - 开闭原则
对拓展开放,对修改要关闭。
(ps:最重要的一个原则,但是也是最难实现的一个,因为需求会一直变化,有时候不得不区修改代码。 这里就要考验架构设计的能力了,需要考虑到需求的持续变化,以及识别和隔离各个变化点)
这里与开闭原则有个相反的定律,叫做熵增定律。所有的一切都是不断变化的,随着变化会越变越复杂。而开闭原则就是一个熵减,可以减少熵增定律带来的影响。
四、关于“架构”的思考
老师说到,架构是一种能力,而不是一种职业。
架构=组成+决策
组成=模块结构+模块关系
决策=约束+设计原则+演化的方向
1. 架构图
架构图是水平层面的业务模块+垂直层面的技术模块结合而成的一个有逻辑的图。
画架构图的目的:将目标系统的接口可视化,通过可见的方式将项目完整的描述出来。
画架构图我们要了解
- 需要画的架构类型
- 确定架构图的关键要素(产品,技术,服务等信息)
- 梳理关键要素之间的关联信息
- 各个信息的信息边界
2. 如何评估一个架构图的好坏呢
我们可以从三个方面来看
- 布局。一个好的架构图有水平的布局和垂直的布局,所以可以看布局上面上下左右前后6个方向的位置信息。
- 颜色。对于核心的流程,可以使用明亮的颜色,点出视觉中心。其他的要素可以使用不那么明亮的颜色。
- 逻辑。是否能够看明白各个组件之间的依赖信息。
3. 架构图氛围业务架构,应用架构,数据架构和技术架构
4. UML图(统一建模语言)
Unified Model Language
以前的各种图形是不统一的,所以经常出现不同公司用不同的流程图的情况,所以后面就统一了一个UML图出来。
UML图的关系
- 泛化(继承关系)-- 带三角箭头的实线,箭头指向父类。
- 实现(实现关系)-- 带三角箭头的虚线,箭头指向接口。
- 关联关系:是一种拥有关系,使一个类知道另一个类的属性和方法 -- 带普通箭头的实心线,可以是单向的,单向只有一个箭头。可以是双向的,双向没有箭头。
- 依赖关系:是一种使用关系 -- 带虚线的箭头,指向被使用者
- 组合关系:业务上面整体和部分不可分开,有关联关系的特征 -- 带实心菱形的实线,菱形指向整体
- 聚合关系:业务上面整体和部分可分开,有关联关系的特征 -- 带空心菱形的实线,菱形指向整体
组合的关系强于聚合,强弱关系如下
泛化= 实现> 组合> 聚合> 关联> 依赖
5. 类图
类图显示了模型的静态结构,特别是模型中的类。基本上把大体的数据交互逻辑都显示了出来。
6. 时序图
描述了对象之间发送消息的时间顺序,显示了多个对象之间的动态协作关系。有下面一些特点:
- 只关注正常流程
- 不关注逆向流程
- 不关注异常流程
- 不关注分支判断
7. 定义好整个框架之后,可以让我们明确知道要做什么不要做什么。
五、23种设计模式
1. 创建者模式
- 单例模式:某个类只能有一个实例,提供一个全局的访问点。
- 工厂方法:定义一个创建对象的接口,让子类决定实例化那个类。
- 抽象工厂:创建相关或依赖对象的家族,而无需明确指定具体类。
- 建造者模式:封装一个复杂对象的构建过程,并可以按步骤构造。
- 原型模式:通过复制现有的实例来创建新的实例。
2. 行为模式
- 适配器模式:将一个类的方法接口转换成客户希望的另外一个接口。
- 组合模式:将对象组合成树形结构以表示“”部分-整体“”的层次结构。
- 装饰模式:动态的给对象添加新的功能。
- 代理模式:为其他对象提供一个代理以便控制这个对象的访问。
- 亨元(蝇量)模式:通过共享技术来有效的支持大量细粒度的对象。
- 外观模式:对外提供一个统一的方法,来访问子系统中的一群接口。
- 桥接模式:将抽象部分和它的实现部分分离,使它们都可以独立的变化。
3. 结构型模式
- 模板模式:定义一个算法结构,而将一些步骤延迟到子类实现。
- 解释器模式:给定一个语言,定义它的文法的一种表示,并定义一个解释器。
- 策略模式:定义一系列算法,把他们封装起来,并且使它们可以相互替换。
- 状态模式:允许一个对象在其对象内部状态改变时改变它的行为。
- 观察者模式:对象间的一对多的依赖关系。
- 备忘录模式:在不破坏封装的前提下,保持对象的内部状态。
- 中介者模式:用一个中介对象来封装一系列的对象交互。
- 命令模式:将命令请求封装为一个对象,使得可以用不同的请求来进行参数化。
- 访问者模式:在不改变数据结构的前提下,增加作用于一组对象元素的新功能。
- 责任链模式:将请求的发送者和接收者解耦,使的多个对象都有处理这个请求的机会。
- 迭代器模式:一种遍历访问聚合对象中各个元素的方法,不暴露该对象的内部结构。