给程序划出组成部分

模块把有关的类型、函数或其他定义组织在一个具名单位中,调用者通过导入或限定名字使用它们。拆分让不同部分可以各自维护,也提供名字空间,减少同名定义互相干扰。模块可以对应文件,但具体对应规则由语言规定,程序中的逻辑边界并不总与目录排列完全一致。

参考:[1]

接口公开什么

接口说明外部可以依赖哪些名字与类型,内部则可以保留具体表示。OCaml的签名能够公开一个抽象类型及操作,而不公开它怎样存储。调用者因此按约定使用数据,维护者也有机会替换实现;若公开的操作含义改变,即使名字仍在,已有调用代码仍可能受到影响。

参考:[2]

导入带来依赖关系

一个模块导入另一个模块,就建立了使用关系,运行时还可能执行被导入模块的初始化代码。Python区分模块自身的名字空间与导入者的名字空间,也维护已导入模块的记录。把工作放在文件顶层可能改变导入时的行为,因此初始化、循环依赖和实际执行入口需要分别安排。

参考:[1]

参数化组件的组合

某些模块系统还允许以模块为参数生成新模块。OCaml的函子可以接收满足指定签名的组件,再构造依赖该组件的实现,例如把不同的比较规则交给同一有序集合结构。这里被复用的是一整组彼此配合的定义,模块系统同时约束输入接口和组合结果的可用内容。

参考:[2]