代码结构

代码结构

在一个健康的开发周期中,代码风格,API 设计和自动化是非常关键的。同样的,对于工程的架构,仓库的结构也是关键的一部分。当一个潜在的用户和贡献者登录到您的仓库页面时,他们会看到这些:工程的名字、工程的描述、一系列的文件。。。只有当他们滚动到目录下方时才会看到您工程的 README。如果您的仓库的目录是一团糟,没有清晰的结构,他们可能要到处寻找才能找到您写的漂亮的文档。

典型的 Python 项目结构如 kennethreitz/samplemod 所示:

README.rst
LICENSE
setup.py
requirements.txt
sample/__init__.py
sample/core.py
sample/helpers.py
docs/conf.py
docs/index.rst
tests/test_basic.py
tests/test_advanced.py

糟糕的特征

得益于 Python 提供的导入与管理模块的方式,结构化 Python 项目变得相对简单。这里说的简单,指的是结构化过程没有太多约束限制而且模块导入功能容易掌握。因而您只剩下架构性的工作,包括设计、实现项目各个模块,并整理清他们之间的交互关系。容易结构化的项目同样意味着它的结构化容易做得糟糕。糟糕结构的特征包括:

  • 多重且混乱的循环依赖关系:假如在 furn.py 内的 Table 与 Chair 类需要 导入 workers.py 中的 Carpenter 类以回答类似 table.isdoneby() 的问题,并且 Carpenter 类需要引入 Table 和 Chair 类以回答 carpenter.whatdo() 这类问题,这就是一种循环依赖的情况。在这种情况下,您得借助一些不怎么靠谱的 小技巧,比如在方法或函数内部使用 import 语句。

  • 隐含耦合:Table 类实现代码中每一个改变都会打破 20 个不相关的测试用例,由于它影响了 Carpenter 类的代码,这要求谨慎地操作以适应改变。这样的情况意味着 Carpenter 类代码中包含了太多关于 Table 类的假设关联(或相反)。

  • 大量使用全局变量或上下文:如果 Table 和 Carpenter 类使用不仅能被修改而且能被 不同引用修改的全局变量,而不是明确地传递 (height, width, type, wood) 变量。您就需要彻底检查全局变量的所有入口,来理解到为什么一个长方形桌子变 成了正方形,最后发现远程的模板代码修改了这份上下文,弄错了桌子尺寸规格的 定义。

  • 面条式代码 (Spaghetti code):多页嵌套的 if 语句与 for 循环,包含大量复制-粘贴 的过程代码,且没有合适的分割——这样的代码被称为面条式代码。Python 中有意思 的缩进排版(最具争议的特性之一)使面条式代码很难维持。所以好消息是您也许不 会经常看到这种面条式代码。

  • Python 中更可能出现混沌代码:这类代码包含上百段相似的逻辑碎片,通常是缺乏 合适结构的类或对象,如果您始终弄不清手头上的任务应该使用 FurnitureTable,AssetTable 还是 Table,甚至 TableNew,也许您已经陷入了混沌代码中。