开发 -- 编程内功
一、业务架构
- 业务上下层:
i.分析业务逻辑的依赖,下层不依赖上层
ii.上层的业务禁止放到下层,而是应该 新增平级函数 或者 抽象上级业务层。 - 先本质,后延展。
本质的问题决定能不能做,延展的问题决定能不能cover所有业务场景。 - 管理方式是不一样的。
技术管理的本质,围绕解决业务问题;
人力管理的本质,围绕发挥人的潜力;
都遵循管理,大多数不是人越多越好。
二、需求阶段
- 给足咀嚼时间
每种结构体设计,一定既要结合真实情况,也要考虑设计的结构体合理性。当下可以设计,但是需要不断反复的思考。 - 安静的想一想
我的天性,性子比较急,思考比较浅层。所以不要那么多的理所应当,学会用大脑思考和推理。【Coverity的一次问题排查】
三、模块设计
-
交互设计
1)配置文件
2)入参设计 -- 用户自定义流程 -
数据结构设计
1)算法设计
2)时序设计 -
类设计(可扩展设计)
1)封装设计
2)接口设计
3)设计模式 -
高可用设计
1)稳定性(超时、异常、中断)
2)日志 -
性能设计
-
开源设计
-
文档
五、协作流程
六、设计模式
-
场景
1.1 业务接近,行为不同
接近的业务抽成父类,不同的行为归纳为子类
1.2 业务不同,功能内聚
模块之间的功能归一,真的太重要了。涉及到组件之间的升级和回滚。 -
具体实现
层级关系用【继承/组合】、同功能属性,方便未来上层调用 【接口】
如:参考kubekey的实现方式
分层 -- 规划接口(多态,将方法变成通用的管道) -- 规划父子 (继承,将相同的实现放到父中统一管理) -- 根据对象设计类,将函数很长的传参抽类等(封装,将函数根据类别形成类)
如:远程操作容器的sidecar操作容器文件
上层下发(如https)根据type类型创建具体的类 === 通用的管道(如调度函数) === 接口判断类型,执行具体类的函数(实现调度函数的抽离) -
设计模式实战
类或者函数之间的创建和交互(结构、方法、交互)
3.1 创建这模式
3.2 方法类模式
策略模式:传入具体的字符串到类或者函数,执行具体的函数。
3.3 交互类模式
七、编码阶段
- map 取 key 要判断
- 不可在for 循环中delete
- 封类的好处: 逻辑归类、传参统一、接口抽象
- 对异常的嗅觉:日志异常、功能异常、流程繁琐等保持钻研的态度,死磕,才能真正避免bug。因为有些历史bug,只是前期需求未做,会因为新的需求暴露。
- 线程开发模型:
底层需求 | 实现方式 | 备注 |
---|---|---|
I/O密集 | 线程:异步事件驱动模式(单线程循环等待事件) | |
CPU密集 | 线程:同步并发处理(来一个任务起一个线程) | |
混合模型 | 由工作线程处理,主线程保持响应 |
- 结构体设计:
-
业务层次决定结构,而不是代码技巧决定!
不同的业务理解,结构也是不一样的。而且最拟合的抽象,主结构体层次几乎是定的,其他辅助结构体可以设计。【参数模板的for循环取数据,应该是根据组件来取,而不是统一取】 -
开发过程比较高效率的是map,但是前端或者展示的结构体,往往是List类型。
不同阶段需要的结构体不一样,也需要支持转换 -
当数据存在多个阶段的结构体时候,这个时候,衡量下以哪个为准。
参数开发的需求,param cr -- configmap。不断迭代的过程中,为了升级,保持configmap的数据是唯一的,param cr是可以不断优化使用方式。
八、架构优化/改造
- 如果技术储备够,更好的设计是相对容易的,难点在于,对既往业务的代码梳理。【分层 + 抽象 + 总结,才能得出最适合的架构。而不是纸上谈兵,拿着设计模式的书指点江山】
- 架构优化,既要参考历史的代码逻辑,又要跳出之前代码的框架,目的为了新的代码,更贴近贴近业务的本质。
状态翻转的架构调整:
crdUtils.GdbDataHeadlessServiceReady: r.CheckIpBoundImage,
最开始自己的想法:
- 为了让自己的架构去适应旧的代码逻辑,做到面面俱到,顾此失彼。
- 重点不是stage的设计,而是整个流程返回值的处理。
正确的想法:
- 旧的代码逻辑适配新的代码框架:把握大方向,再贴合业务的情况下,旧的代码逻辑适配新的代码框架。r.CheckIpBoundImage 合并了之前的两个函数 check && reconcile。
- 新的代码框架不可能面面俱到:大方向已经优化的前提下,适配的过程中,小方向可以增加算法复杂度。翻转之后,不需要引入额外的cr stage更新,先做到代码层级的更改。
pipeline
-- child module 【通过chlid module 子函数实现stage注册,然后通过 father module 通用函数实现通用逻辑 】
-- child stage 【通过chlid stage 子函数实现action注册,然后通过 father stage 通用函数实现通用逻辑】
-- child action 【执行具体指令】