最近在做大量的代码 Review 的工作,尝试整理出一些大家在写代码时要避免的一些问题,同时也在读《代码整洁之道》和《代码里的世界观》。也在知识星球(同公众号名:Python程序员杂谈)中发了一些关于代码设计的内容。
1. 不做需求翻译器
绝大部分程序员在入门编程时学习的第一门课程/书籍差不多都会是《 XXX 程序设计》,但是很多人在实际写代码时却完全不做任何设计的工作,只是单纯的把产品的需求翻译为可执行的代码。对于软件开发来说,这是入门阶段,毕竟程序员的第一要务还是要把产品的需求转变为可运行的系统/软件。 这种做法就像我们刚开始学习写作文时那种流水账式的写法,能表达信息(实现功能),但是内容冗余,不易维护。
所以我们在接需求时,需要做的是充分理解产品需求,什么叫充分理解产品需求呢?实际工作中很简单,你能给其他人讲明白要做的产品需求是啥即可。之后需要做的是根据产品需求思考应该怎么实现,对其中的逻辑做一些抽象。
单纯讲可能不太容易理解,举个例子,有这么一个需求,写一个函数判断用户上传图片文件的是否合法。需求描述是,如果后缀是
.txt
则返回不合法,如果后缀是
.gif
返回不合法,如果后缀是
.mp4
返回不合法。(等一系列不合法的后缀)。
那么怎么实现呢,如果不加思索的写代码就会出现这么个状况:
def is_valid_filetype(suffix):
if suffix == 'txt':
return False
if suffix == 'gif':
return False
if suffix == 'mp4':
return False
return True
这样写代码的问题是什么?暂且不说需求问题。代码的问题在于,如果我需要新增一个不支持的类型,那就要新增一个
if
判断。显然更好的做法是:
invalid_suffix_set = {'txt', 'gif', 'mp4'}
def is_valid_filetype(suffix):
return not suffix in invalid_suffix_set
这么一改看起来简单多了,消除了
if
分支语句(这个是代码设计中很重要的部分),并且改成了基于配置的方式,新增不合法后缀只需要去修改配置
invalid_suffix_set
即可,不涉及代码逻辑改动。
但是我们再回过头来看下需求,是不是有什么不妥。
写一个函数判断用户上传图片文件的是否合法
。相信读者已经看出来了,这个需求其实有问题:需要枚举出所有不合法的后缀,鬼知道有多少中文件后缀。虽然我们做了不合法后缀的配置,但是还需要经常去做修改来支持新发现的文件后缀。
所以应该去反问下产品,哪些文件是合法的?显然这是一个可以有限枚举的内容。最终可能得到的代码是这样:
valide_suffix_set = {'png', 'webp', 'jpg', 'jpeg'}
def is_valid_filetype(suffix):
reutrn suffix in valide_suffix_set
2. S.O.L.I.D 原则
SOLID 这个词很多人可能没有听说过,这是程序设计时经常用到的一些原则,如果你看过设计模式,应该知道,所有的设计模式都会基于这些原则。SOLID 什么意思呢?为了避免不了解的读者此时关闭文章去搜索(笑),我列到这里:
在程序设计领域, SOLID(单一功能、开闭原则、里氏替换、接口隔离以及依赖反转)是由罗伯特·C·马丁在21世纪早期[1] 引入的记忆术首字母缩略字[2][3],指代了面向对象编程和面向对象设计的五个基本原则。
- S 单一功能原则 认为对象应该仅具有一种单一功能的概念。
- O 开闭原则 认为“软件体应该是对于扩展开放的,但是对于修改封闭的”的概念。
- L 里氏替换原则 认为“程序中的对象应该是可以在不改变程序正确性的前提下被它的子类所替换的”的概念。
-