组件/框架设计原则

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上。

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

相关推荐
梓仁沐白6 小时前
ubuntu+windows双系统切换后蓝牙设备无法连接
windows·ubuntu
九鼎科技-Leo10 小时前
什么是 WPF 中的依赖属性?有什么作用?
windows·c#·.net·wpf
Yang.9912 小时前
基于Windows系统用C++做一个点名工具
c++·windows·sql·visual studio code·sqlite3
我不瘦但很逗12 小时前
Windows下使用DBeaver连接云数据库(MySQL)
数据库·windows
ashane131414 小时前
Java list
java·windows·list
万里沧海寄云帆14 小时前
Word 插入分节符页码更新问题
windows·microsoft·word
dot.Net安全矩阵15 小时前
.NET 通过模块和驱动收集本地EDR的工具
windows·安全·web安全·.net·交互
编程修仙16 小时前
Collections工具类
linux·windows·python
程序员小羊!18 小时前
高级 SQL 技巧讲解
windows
xiangshangdemayi19 小时前
Windows环境GeoServer打包Docker极速入门
windows·docker·容器·geoserver·打包·数据挂载