什么是原则
设计原则是构成任何优质产品基础的一系列考虑因素。
都有什么样的原则
SOLID: 面向对象的原则
函数编程原则: https://dev.to/jamesrweb/principles-of-functional-programming-4b7c
ACID/BASE/CAP: 数据库特性和原则
设计(UI)的原则: https://www.figma.com/community/file/817913152610525667
为什么要用设计原则
设计原则可帮助团队进行决策。一些简单的原则或建设性的问题将指导您的团队做出适当的决定。
原则:
可视性(Visibility)
可视性决定了 技术的人机交互能力。把任何有助于理解,开发的数据直接放到一个可视平台将大大提高工作效率。
- 命名规范,统一命名
- 状态可视化
- 有效的错误包装
- 状态机状态可视化
- 中间变量/私有变量可视化
- 轨迹可视化
- 有效的log
- 特有轨迹信息建设
可调试(Debuggability)
以下手段可以达到高可调式
- 完备的可视化
- 动态Config设计
- 策略化参数,参数化所有用到常量
- 参数可视化
- 明确的log等级设计
- 结合下边A/B test设计
可测试(Testability)
可以被快速调试
- 策略化参数,参数化所有用到常量
- 透明化
无状态(Stateless)
- 无状态有利于水平扩展, 易于维护。
- 状态可以转移给专门的状态管理者,如各种数据库,文件系统等。
- 状态和逻辑的分离
- 状态机使用
隔离(低耦合)
- 低耦合的一个重点就是减少对外部状态的依赖
- 拒绝直接访问其他微服务(模块)的数据库
- 统一状态CURD的入口/Database的单一拥有者
冗余
- 防止任何单点故障
- 生产环境Loadblance后至少需要2个服务实例;
- 冗余是防止机器/系统/服务单点故障;
- 任何技术环节都需要一定的冗余,包括人。
一致性
- 如果数据有多个入口/来源/储存/使用 位置,则永远有一致性问题。
- Cache
- Search engine
- Web
- 业务场景确定区分
- 最终一致性
- 强一致性
- 异步同步保证一致
- 提供Query/Validation验证一致
监控(Metrics)
- 任何重要的数字都可以是Metrics
- Metrics天然属性,是会随着时间变化
- 技术
- P95 速度,错误响应的比率
- FCP,FMP
- 容量,使用率
- 产品
- 用户在线时间,平均时长
- 特定用户群(profile)使用率
- 特定feature 使用率,时长
- 服务
- 在线Ticket响应时间,解决问题时间
- SLA
- 不一样的统计
- 环比/同比
- consolidation (roll-up), drill-down, and slicing and dicing.
线性算法O(n)
- 业务代码时间复杂度必须是<=O(n)算法, 如果大于O(n) 的,超线性的算法会带来非常严重的性能和扩展瓶颈;
- 也要尽量达到最小的Overhead,都是O(n),2n 永远比n浪费一倍的资源。
伸缩性(Scalability)
- 当业务增加n倍,依靠简单加服务器数量解决问题。
- 对于微服务,一般服务无状态就可以达到计算伸缩性
- 对于有状态(DB),通过一下手段达到伸缩性
- 分库分表 - sharding
- DB代理 - DB proxy
异步调用(hollywood principle)
- 面向对象的IoC;
- 在银行排队等待,还是拿号码等着被叫。
自动化(Do not repeat yourself principle)
重复是效率的最大敌人, 尽量自动化所有机器可以搞定的步骤
- 自动化部署(deploy)
- 自动化测试(test)
- 自动化调研(investigation)
- 自动化解决问题(fixup)
小步迭代,快速迭代
大部分线上故障是由于变更(发布新功能或者改变功能)造成的, 不要做特别大的改动,小步快速迭代,增量发布,降低变更的风险
回滚设计
- 回滚相当于是系统的保险, 设计需要保证可以快速回滚,如果监控到有问题,马上回滚
兼容性设计(toleration/coexistence)
- 新代码, 老数据
- 老代码,新数据
- 新接口,老接口
禁用设计 (A/B Test & Feature toggle)
- A/B test 不只产品的思路,更是代码的思路。代码永远也可以做A/B test;
- 产品/功能的设计也最好都使用Feature toggle。可以一键开关;
- 开关可以单独为特定用户群体打开或者关闭。
幂等性(Idempotence)
- f(f(x))=f(x)
- 服务之间的ID的设计和依赖 - Transaction IDs
Links
- https://www.w3.org/People/Bos/DesignGuide/toc.html
- https://principles.adactio.com/
- Coding Principle
- https://www.figma.com/community/file/817913152610525667
- https://dev.to/jamesrweb/principles-of-functional-programming-4b7c
- https://www.digitalocean.com/community/conceptual_articles/s-o-l-i-d-the-first-five-principles-of-object-oriented-design
关于中台的看法
这里将更多的会贴合我们的设计原则讨论中台: 1. 不管是产品中台,还是技术中台,都可以贴合 DRY法则(不重复轮子),以及低耦合法则(有专门的服务(群)来负责特定任务)。 2. 比如标准商品中台(标品是有国家具体规定的);标准书籍中台。再比如不同业务线用到的RBAC权限控制就可以做成中台,防止重复造轮子。用户体系中台可以提供各个语言的SDK给大家用。这本身就是一个platform了。 3. 技术的比如Cache中台。也都是很好的诠释了DRY法则。 4. 中台指的是台,也就是platform。从小到大我们有 Object-> micro-service -> platform,不同层次的设计。它们遵循一些公用,以及特有的设计法则,比如这里提到的DRY。再比如单一职责。还有低耦合。 5. 中台除了避免了重复造轮子,还会有其他优点,比如用户体系的中台单独把控系统设计特性(伸缩/可调/监控,等等),会直接把系统设计最佳实践直接带给每个利用中台的服务,直接提升服务的质量防止短板。
问题一:如何应对简单功能成长为复杂级功能?
1.简单功能设计之初,应该基于什么原则去设计?
2.简单功能没有好好设计,已然成长为复杂级功能(难以梳理,没有文档,不知道包含多少功能点),如何重构?
问题二:如何保持代码的清洁度?
1.主干分支中包含很多不用的代码,或者不确定有没有在用的代码;
2.引用了某个包,但是代码中没有相关的使用(无法真正确定,到底有没有什么地方在使用);
3.滥用全局变量,localStorage缓存等,但是要在原来的功能增加新的功能,只能在原有的设计体系中增加新的代码;
问题三:如何保证代码可读性?
1.复杂业务逻辑实现缺乏相应的设计/实现文档
这些问题都很好
1. 对于复杂的功能,这里我们稍后会添加可扩展性(Extendability)。我们最开始设计的时候要把控可扩展性,最好站在领域专家位置(Domain expert)进行建模。这样可以避免后期refactor。
2. 我们也随时保持Refactor的态度,和思路。不断的对系统重新审计这些设计原则。
3. 代码的可读性,这里我列到了Visibility里,我觉得确实应该独立强调下,所以会单独列出。
4. 重构的原则,依然是这些设计原则。
5. 任何设计都需要文档,对于知识库(kownlage base)的建设,我列在了冗余里,知识库不应该只在某一位的开发的大脑中,而是需要冗余到文档里。
6. 这里讨论更多的是系统设计的原则,我们同样可以建设js代码原则,比如应该怎么用全局变量,code style等,你很好的提出这些问题,那能不能进一步把你的想法和大家讨论好形成代码原则呢?
7. 设计文档是必须的,文档不会局限于文字,可以是图表,数据流图,时序图,ER图等。这个也可以单独列出来讨论,我们可以一起总结最佳的“技术文档原则”。
稳定性可以单独拿出来的,监控里 SLA很重要的就是可用性。 提到的代码review 也很重要,因为本文档主要是系统设计,对于review的原则可以参考代码的原则。 Coding Principle