一个目的一种实现:少即是多

不要封装太多的实现方法,会造成使用复杂度。一个目的提供一种方法,提供的太多,反而让使用者陷入学习复杂性。 现象 写一个方法要到处去找合适的调用,挺难受。 尤其是 sql 查询的方法。 为什么会有这种感觉: 确实是项目大小导致的复杂性区别; 确实是归类的约束不强,导致有些零散; 写一个新的成本太大了,少即是多,只提供一种实现方法。 核心:一个目的一种实现 不要封装太多的实现方法,会造成使用复杂度。 一个目的提供一种方法,提供的太多,反而让使用者陷入学习复杂性。 良好的 util 封装 高内聚:一类方法放在一起,不然难找,也不知道想要的有没有、需不需要新写一个。比如 sql 一个文件,qemu-img 一个文件; 使用文档:必须的,要不然找代码效率很低; 一个目的提供一种方法:提供的太多,反而让使用者陷入学习复杂性。 小结 一个目的一种实现,少即是多; 不要封装太多的实现方法,会造成使用复杂度; 良好的 util 封装:高内聚、使用文档、一个目的一种方法; 提供的太多,反而让使用者陷入学习复杂性。

February 28, 2026 · 1 min · 29 words · 文叨叨

封装不在于使用复杂度,而在于使用频率

如果一个工具仅仅在一两个地方调用,那无所谓封装。如果一个工具通篇各处都在调用,那就一定要封装了,即便这个工具仅仅是一行命令。 核心观点 这也是上面 qemu-img 要封装的一个原因。 如果一个工具仅仅在一两个地方调用了,那无所谓封装。 如果一个工具通篇各处都在调用,那就一定要封装了。即便这个工具仅仅是一行命令。 比如我们的 qemu-img、virsh、sql。 为什么 因为使用频率高,意味着: 出问题的概率高,需要统一处理; 版本升级的影响面大,需要统一应对; 日志、统计、重试等切面能力需要统一提供。 小结 封装不在于使用复杂度,而在于使用频率; 一个工具仅在一两个地方调用,无所谓封装; 一个工具通篇各处都在调用,一定要封装,即便只是一行命令; 使用频率高,出问题概率高、影响面大,需要统一处理。

February 22, 2026 · 1 min · 19 words · 文叨叨

调用第三方一定要封装,哪怕仅仅是一个命令行

调用第三方工具一定要封装,哪怕仅仅是一个命令行。封装的好处:应对版本变化、方便做切面、简化使用、提供统一方法。 现象 qemu-img 是一个典型的例子。 为啥要封装? 底层工具版本变化导致的参数校验变化; 方便做切面,可以做一些统计、日志、重试、timeout 等; 简化使用,底层工具参数众多,大部分都用不上; 提供实现目的的统一方法,少即是多,实现一个目的最好只有一种方法。 封装得好是什么样 qemu-img 自认为封装的挺好。 对于一些版本不支持的参数,明确打印出来了,通过 error 日志一眼看出问题,这效率,QA 也能排查了。 比如: logger.error("QemuImg commit: qemu-img commit [-d] not supported") 一个封装示例 class QemuImg(object): """ qemu-img Package """ @classmethod def commit_str(cls, filename, image_opts=None, fmt=None, skip_empty=False, host=None, ): """ qemu-img commit [--object objectdef] [--image-opts] [-q] [-f fmt] [-t cache] [-b base] [-d] [-p] filename The image FILENAME is emptied after the operation has succeeded. If you do not need FILENAME afterwards and intend to drop it, you may skip emptying FILENAME by specifying the -d flag. """ if fmt and fmt not in ["raw", "qcow2"]: logger.error("QemuImg commit: unsupported format: %s" % fmt) return None if image_opts and not isinstance(image_opts, dict): logger.error("QemuImg commit: image_opts must be a dict") return None if skip_empty: has_d_cmd = r'qemu-img -h | grep commit | grep "\-d"' ret = exec_cmd(has_d_cmd, remote_host=host) if not is_cmd_ok(ret): logger.error("QemuImg commit: qemu-img commit [-d] not supported") return None cmd_str = "qemu-img commit" if fmt: cmd_str += " -f %s" % fmt if skip_empty: cmd_str += " -d" if image_opts: image_opts_str_li = ["%s=%s" % (key, value) for key, value in image_opts.items()] if image_opts_str_li: cmd_str += " --image-opts %s" % ",".join(image_opts_str_li) if filename: cmd_str += " %s" % filename logger.info("QemuImg commit cmd: %s", cmd_str) return cmd_str 小结 调用第三方工具一定要封装,哪怕仅仅是一个命令行; 封装应对版本变化、方便做切面、简化使用、提供统一方法; 对于版本不支持的参数,明确打印出来,QA 也能排查; 少即是多,实现一个目的最好只有一种方法。

February 21, 2026 · 1 min · 212 words · 文叨叨