组件/框架设计原则

Windows应用软件开发,会有很多常用的模块,比如数据库、配置文件、日志、后台通信、进程通信、埋点、浏览器等等。下面是目前我们公司windows梳理的部分组件,梳理出来方便大家了解组件概念以及依赖关系:

每个应用里,现在或者以后都可能会存在这些模块。以我团队开发的全家桶为例,十多个应用对后台访问,就会有十多个重复的模块。后台通信的设计、开发、BUG修复,都是重复工作量。

业务/通用组件:通用模块,流程/逻辑基本是固定不变的,变的部分是上层业务调用,所以不变的部分我们需要把它固化下来、稳定下来,减少代码的复用、提高共性代码的稳定性、提升项目/人员的开发效率。

框架组件:除了通用模块,还有一些流程比较复杂。比如软件启动时很多业务的处理,需要框架来梳理、组织好业务流程,使其业务模块分层合理、依赖关系清晰。

所以我们抽取/开发了一些组件,以后还会有更多的组件。组件的开发/维护,大家都会参与,所以需要同步一些如何做好、做稳的概念。

组件调用方

组件尤其是通用组件,我们能支持更多方向的,一定要提供好支持。站在其它开发人员,考虑更多应用、业务的使用及场景,有这些思维,会让你的组件设计更加完善、可用性更高。

  • 开发人员 - 自己、其它开发小伙伴、外部第三方开发人员
  • 各个应用软件 - 内部软件、ISV以及ODC软件
  • 业务场景 - 会议、医疗、教育等

当然,我们设计组件时也要掌握一个度,没有设计或者过度设计都不是我们的初衷。所以按照初衷-要尽可能提高效率(团队效率),即易维护、易阅读理解以及易扩展等,组件设计的方向也就不会有大问题。

组件设计原则

组件是应用软件开发的基石,组件不稳定,应用不可能稳定下来。所以我们需要考虑怎么做好组件。

如何把组件设计好,怎么评估组件的好坏?组件设计评估,有哪些维度

结合我的工作经验,吸收到的知识点,以下是我个人的一些总结:

1.所见即所得

"所思即所见,所见即所得",这是佛学里的思维。

我们软件设计也有这个"所见即所得"的原则,看见什么就是什么,执行的逻辑就是看到的方法/协议名称。

组件、接口及方法,应该是只做名称对应的实现。不得包含未知的逻辑,比如接口里同时存在Get、Check,在Get方法内调用了Check。又比如执行元素的缩放,缩放方法中不应该存在旋转逻辑如设置角度。

也不得只实现部分逻辑,比如清空用户缓存,结果内容只执行了部分路径下的数据清空。

所见即所得,关键点是:

  • 对外的定义,要符合业务的第一性原理,回到组件设计的初衷,该有的功能/逻辑一个也不能少。
  • 内部的逻辑,围绕着协议名称去实现,要覆盖且不脱离原有的初衷。

另外,solid中的单一职责原则,也是"所见即所得"原则中的一部分概念,设计要清晰、单一。

2.简单

简单,意思是对外要简洁、单一。所有的组件,都是给自己以及其它开发人员使用的,给各个应用调用的,那我们就需要考虑使用成本以及学习成本。

调用组件时,能够以最快的速度理解接口/组件的使用,以最快的速度完成组件的调用,这是组件开发人员需要考虑的。如果给出的接口以及调用流程太过复杂、混乱,调用时不得不花很多时间沟通、理解如何调用;项目上也会因为调用流程复杂,导致业务逻辑复杂,降低后续的可维护性、提高BUG定位的复杂性。

所以我们设计组件/接口,需要:

  • 尽量少暴露内部实现。
    • 不需要开放的类要隐藏
    • 外界不需要关心的属性要设置internal
    • 外界用不到的方法,设置internal。或者删除对外暴露接口里的冗余方法
  • 实现要简单
    • 对外暴露的接口/方法,尽可能的减少数量,能合并的合并
    • 对外暴露的接口/方法,尽可能的减少参数,以最少参数实现相应功能

用一句话总结,就是最少知识原则(迪米特原则)

对外暴露越少越好,暴露的少肯定能减少耦合。我们常提的封装就是这个意思,高内聚低耦合,内部实现复杂的逻辑,外部减少耦合。

3.完整

完整是指组件,要提供一整套完整的功能,能全部覆盖对应场景,不能开发一部分然后提供出去使用。

  • 尽可能的将应用内与这个组件相关的通用代码,挪到组件内
  • 尽可能的满足后续业务的需要。不管是新增需求、新增应用、新增场景,后续都应该尽量无需新增代码,即可满足业务需求

比如,我们做OTA组件,那你应该把升级的所有实现放在OTA组件里。一个组件做一类的事情,但这个组件一定要把这一类的事情做完整。完整的意思是,在应用使用OTA组件时,能通过组件完成所有OTA的相关操作。比如检验是否需要升级,这段逻辑如果放在应用层去做,那就会存在冗余的重复代码,说明OTA组件未设计完整、没有实现完整。

当然如果你这样实现内部实现过多,那可以拆分一些独立的组件,如双网卡可以拆分为双网卡使用组件、双网卡修复组件。

完整,意味着可用性高,这一类场景的组件能支撑更多的业务。

4.易维护

易维护指的是,组件内部的代码实现以及设计应该容易维护。开发通用组件,后续可能会有BUG,如何保证定位问题、解决问题的高效呢?那就需要内部清真的代码实现、清晰的代码设计。如果一堆不安全代码、实现流程复杂、依赖关系混乱,肯定很难定位问题根因,修改代码后容易牵一发动全身,如果是后面的开发人员,估计他会吐N多口水。更不用说业务组件了,业务组件如果内部不易维护,BUG肯定一堆又一堆。

如何提升代码的可维护性?可以从以下几个方面着手:

  • 代码实现要简洁
  • 类、函数名称,要简单、易理解
  • 类与类、模块与模块的关系要尽量简单,保持线性原则,模块分层合理

一般来说,只要你的代码易读易理解,可维护性不会差到哪里去。拥有结构化思维,代码的流程肯定不会乱。

可维护性还有很多要考虑的,就比如我们大部分组件内部也需要考虑扩展性、复用性。把可变的部分设计成抽象类或者接口暴露给上层,由业务注入变化/扩展的实体;把一些不变的部分抽成工具类或者基类,通过静态或者组合来调用,减少内部依赖。

更深的,那就需要熟练掌握设计原则、设计思想、编程范式、架构思维,利用你的重构意识、抽象意识、封装意识、甚至"洁癖"意识,创造优秀的代码。

5.稳定

稳定性,包括性能以及质量。代码稳定,是衡量组件的一个重要指标,是一个状态。

组件不稳定,内部实现脏、乱、差,会体现到应用软件的BUG上。

设计要素不是独立的,而是有些有关联的。比如组件易维护,组件稳定性一般不会差到哪去。提升了稳定性,代码的可用性也会提升;
总之,做好模块化解耦的组件,能提高团队开发效率,后续有精力往更深的技术方向研究、以及追求极致的用户体验。

相关推荐
love530love13 分钟前
ComfyUI MediaPipe 终极填坑:解决 incompatible function arguments 报错,基于代理模式的猴子补丁升级版
人工智能·windows·comfyui·mediapipe·猴子补丁·monkey patch·python 3.12
今夕资源网39 分钟前
Windows Terminal更舒适的命令行环境 仅11MB 支持并行运行WSLLinux子系统 github开源项目
windows·github·命令行·cmd·terminal
java_logo2 小时前
SiYuan 思源笔记 Docker 部署终极指南:Windows+Linux 双平台
windows·笔记·docker·思源笔记·思源笔记部署·docker部署思源笔记·思源笔记文档
测试员周周4 小时前
【AI测试系统】第1篇:LangGraph 实战:用 State Graph 搭建 AI测试流水线(4 步编排 + RAG 增强 + 完整代码)
linux·windows·python·功能测试·microsoft·单元测试·多轮对话
祖国的好青年4 小时前
VS Code 搭建 React Native 开发环境(Windows 实战指南)
android·windows·react native·react.js
love530love4 小时前
Python 3.12 解决 MediaPipe “no attribute ‘solutions‘” 终极方案:基于全版本硬核实测的避坑指南
开发语言·人工智能·windows·python·comfyui·mediapipe·solutions
YJlio5 小时前
Windows Internals 读书笔记 10.3.3:Task Scheduler 架构详解
人工智能·windows·笔记·python·学习·chatgpt·架构
微软技术分享6 小时前
Windows平台下CUDA安装及llama.cpp使用教程
windows·llama
CHANG_THE_WORLD6 小时前
<Fluent Python > 2. 第二章:序列的数组
网络·windows·python
独自破碎E6 小时前
解决 Windows 虚拟内存迁移失败的全过程实录
windows