认知边界

如何控制系统软件的复杂度

2023-10-23 16:52:48 98

本文总结自参考链接的内容。

概要

本文主要讨论了几个减少软件系统复杂度的方法。首先是对于非核心组件,应该购买现成的软件而不是自己研发,以减少复杂度。其次是通过统一编码规范、代码审查和重构、统一命名规范等方法来降低代码复杂度。此外,文章还提到了在关键函数和变量命名上反映业务而不是程序逻辑,以及保证系统架构上的可沟通性等方法来简化系统。最后,文章还强调了编写单元测试和自动化部署来加快质量反馈时间。

软件的复杂性来自两个方面:本质复杂度和偶然复杂度, 控制复杂度的核心是接受本质复杂性, 消除偶然复杂性。

对于非核心组件能买就买

不应该自己去投入研发数据库、调度系统、消息队列、分布式缓存等软件。通过购买的方式,研发团队完全不用承担这些复杂度,也能轻松地支撑好用户规模的增长。


减少编码过程带来的复杂度

  1. 统一团队的编码规范,确保所有成员使用相同的风格和命名约定,建立清晰的文档和开发指南;
  2. 定期进行代码审查和重构,及时发现并解决冗余、重复或不必要的代码;
  3. 采用统一的命名规范,使不同模块中的概念命名一致,减少理解成本;
  4. 推行系统架构的设计审核,及时发现并纠正不符合标准和设计原则的代码;
  5. 加强团队内部的沟通和协作,提高成员对系统整体的理解和把控;
  6. 提供培训和指导,帮助团队成员理解系统架构和设计原则,以便他们能够在开发中做出更合理的选择;
  7. 注重持续集成和自动化测试,确保系统在被多人开发时的稳定性和可维护性。

关键函数变量命名上反应业务,而不是程序逻辑

比如

function emailsForCustomers(customers, goods, bests) {
  var emails = [];
  for(var i = 0; i < customers.length; i++) {
    var customer = customers[i];
    var email = emailForCustomer(customer, goods, bests);
    emails.push(email);
  }
}

function biggestPurchasePerCustomer(customers) {
  var purchases = [];
  for(var i = 0; i < customers.length; i++) {
    var customer = customers[i];
    var purchase = biggestPurchase(customer);
    purchases.push(purchase);
  }
}

应该改成:


function emailsForCustomers(customers, goods, bests) {
  return map(customers, function(customer) {
    return emailForCustomer(customer, goods, bests);
  });
}

function biggestPurchasePerCustomer(customers) {
  return map(customers, function(customer) {
    return biggestPurchase(customer);
  });
}

架构上,保证跨系统之间可沟通性

  1. 避免不同子系统对同一概念有不同的名称。
  2. 建立跨团队、跨部门的系统架构师角色,负责对系统整体进行设计和控制。
  3. 确保团队目标一致,避免不同团队在负责不同目标的同时对系统进行开发和演进。
  4. 加强沟通协作,提高团队间的协同性,避免各个子系统之间独立开发导致的系统复杂度增加。
  5. 关键问题域要有唯一的负责人
  6. 进行定期的复杂度分析和梳理,及时发现系统中的冗余和重复的部分,合并或重构相关的子系统,减少概念和术语的重复出现。
  7. 设计文档应当写清楚系统上下文图,以便清晰地展示系统不同组件和子系统之间的关系,帮助工1. 程师更好地理解系统整体结构和各部分之间的依赖关系。
  8. 加强团队协作和共享知识,在团队成员之间建立一个统一的语言和上下文,减少交流和理解时的翻译成本和误差。
  9. 注重培养工程师的系统思维和架构能力,使他们在需求提出时就能够考虑系统上下文,从整体和长远的角度思考问题,并能够提出合适的解决方案。


通过写单元测试,自动化部署加快质量反馈时间

单元测试应该具有以下特点:

  1. 提供清晰的质量反馈:每次运行单元测试,应该能够及时获得有关代码质量的反馈,避免出现等待多个小时或多天的情况。
  2. 包含必要的断言(assert):单元测试应该包含适当的断言,用于验证代码的预期行为和输出。
  3. 稳定可信的测试集:编写的单元测试应该是稳定的,即代码是好的,测试是正常通过的。测试集应该可靠,可以被信任,确保捕捉到代码中的问题。
  4. 执行时间较短:单元测试应该在短时间内运行完成,避免长时间等待,可以增加开发效率。
  5. 手动编写单元测试而非代码生成:为了保证单元测试的有效性和意义,应该手动编写单元测试代码,而不是依赖于代码生成工具。这样做可以更好地理解代码逻辑和需求,并确保测试覆盖范围。




参考:

https://mp.weixin.qq.com/s/f82GBadLcQJCiFHcGWzkCA

AutoAnimate 自动为整个前端应用添加合适的动画的工具

AutoAnimate是一个可以自动为整个应用添加合适的动画的工具,不需要用户自己决定或配置动画。它的原理是监控给定DOM节点的所有子节点的特殊操作,包括节点的插入、删除和移动,并在这些过程中插入相应的动画。AutoAnimate可以帮助提升用户体验,而且它支持现在所有主流的框架,包括React、V
2023-08-26
开发者工具箱 Devkits [闭源]

开发者工具箱 Devkits [闭源]

闭源软件,基于 wails 开发
2023-08-28
声准 SoundSavvy 软件, 准确合成 TTS 音频的解决方案

声准 SoundSavvy 软件, 准确合成 TTS 音频的解决方案

声准 SoundSavvy!该产品是一款结合了 TTS 技术的语音生成工具,为用户提供高质量、准确的音频文件。
2023-08-28
Meta AI 发布 OCR 工具 Nougat

Meta AI 发布 OCR 工具 Nougat

Meta AI 发布 OCR 工具 Nougat,可轻松将学术 PDF 转换为 MultiMarkdownMeta AI 最近发布了一款 OCR 工具 Nougat,它可以将学术 PDF 文档转换为 MultiMarkdown,尤其擅长处理复杂数学公式。Nougat 基于 Transformer 模
2023-08-30
Aidea:一款集成主流大语言模型和绘图模型的开源Flutter应用程序

Aidea:一款集成主流大语言模型和绘图模型的开源Flutter应用程序

如果你正在寻找一个值得学习的 Flutter 前端项目,那么我强烈推荐你看看 Aidea 这个项目。Aidea 是一个集成了主流大语言模型和绘图模型的应用程序,采用 Flutter 开发,代码完全开源。Aidea 支持多种功能,包括 GPT-3.5/4 问答聊天、国产模型(通义千问,文心一言)、文生
2023-08-30
卫星照片上的B-2轰炸机为什么有彩色条纹?

卫星照片上的B-2轰炸机为什么有彩色条纹?

背景这张照片来自谷歌地图,上面拍摄到了一架B-2轰炸机的飞行过程。与其他卫星图像相比,这张照片有明显的彩色条纹。提高分辨率的技巧 普通数码相机只有一个传感器,一次只能拍一张照片。但高分辨率的卫星图像不是这样的。它们采用了一种类似JPEG图像编码的技巧来模拟更高的分辨率。具体做法是先拍摄一张高分辨率的
2023-09-06
如何控制系统软件的复杂度

如何控制系统软件的复杂度

本文总结自参考链接的内容。概要本文主要讨论了几个减少软件系统复杂度的方法。首先是对于非核心组件,应该购买现成的软件而不是自己研发,以减少复杂度。其次是通过统一编码规范、代码审查和重构、统一命名规范等方法来降低代码复杂度。此外,文章还提到了在关键函数和变量命名上反映业务而不是程序逻辑,以及保证系统架构
2023-10-23
移轴摄影 Tilt-shift Photography

移轴摄影 Tilt-shift Photography

移轴指的是镜头与感光器CMOS之间连接的部分是可动的。 可动部件带来的一个好处就是:在不移动相机本身的前提下,利用沙姆定律 可以拍摄出特定景深的物体。相机中景深是指:在相机拍摄的画面中,被摄物体前后距离一定范围内都能保持清晰焦点的深度范围。沙姆定律 Scheimpflug principle这个定律
2023-11-05