命名和组织约定
我们必须先加上一条免责声明。本章给出的命名约定和组织理念并非绝对真理。正如我们之前所见,最重要的是尊重项目中已有的约定,并与团队保持一致。如果你认为有必要,可以根据自己的需要调整这些规则。同样,最重要的是运用常识和逻辑,并尽可能清晰明了。
首先来谈谈源文件的命名。很明显,不同技术的命名规则是不同的(例如,根据你使用的是某种框架还是其它框架,良好做法可能会发生变化)。不过,我们可以注意到一些几乎随处可见的约定。
类文件和接口文件
PHP:定义类、抽象类或接口的 超文本预处理器(PHP)源文件应与相关类或接口的名称相同。例如,Foo 类应在 Foo.php 文件中定义。这种命名技术不仅是一种约定俗成的做法,还具有真正的技术意义。事实上,PHP 的自动加载机制会假定你的文件定义了一个同名的类。自动加载机制允许 PHP 自动发现应用程序中定义的类,这要特别感谢命名空间(我们稍后再谈,因为命名空间与项目中的文件组织直接相关)。如果对文件及其定义的类采用不同的命名方式,自动加载很可能会失败并引发错误。在各种语言和全球开发者社区中,最常见的类命名方式是 PascalCase。这种命名方式只是在每个单词的开头添加一个大写字母。因此,如果使用 PascalCase,名为 "我的超级服务类" 的类将被命名为 MySuperServiceClass
。还有其它命名方式,我们将介绍其中一些,以及它们在哪些情况下适用。
可执行文件
作为可执行的命令行脚本,PHP 文件非常倾向于用小写命名。PHPUnit 测试框架就是一个很好的例子。实际上,它是终端中的一个系统命令。实际上,它只是一个 PHP 脚本。我们使用连字符作为单词分隔符。这种命名方式称为 kebab-case。命令行程序大多使用这种命名方式。众所周知的 apt-get
、docker-compose
和 git cherry-pick
就是完美的代言人。没有什么能阻止你用其它方式命名你的可执行文件,一切都会很顺利。不过,通过以这种方式命名 PHP 编写的命令行应用程序,可以为绝大多数命令提供统一的命令行界面(CLI)体验。这正是我们在 PHP 中开发命令行应用程序时所希望的:让它与更多传统的系统命令融为一体。
web 资产和资源
还有一种情况是使用 kebab-case 风格,主要用于公共网络资源,特别是 JavaScript、层叠样式表(CSS)和超文本标记语言(HTML)文件。事实上,kebab-case 是一种易于阅读和理解的命名样式,无论你是否从事技术工作。此外,使用这种符号,搜索引擎能更好地理解资源的语义。因此,如果你想进行搜索引擎优化(SEO),就必须使用这种命名方式。举个例子:与 /contactus
或 /ContactUs
这样的统一资源定位符 (URL) 相比,/contact-us
这样的 URL 要常见得多,甚至自然得多。如果你必须处理前端文件,这一点就显得尤为重要。
命名类、接口和方法
正如我们在前面几章中所看到的,代码中应禁止使用缩写。现在的集成开发环境(IDE)功能强大,可以自动完成使用的类和方法的名称。因此,反复缩短类名、方法名和变量名是没有用的,因为这只会造成混淆。这也是为什么抽象类应以前缀 Abstract 开头(如 AbstractMailer),而接口应以后缀 Interface 结尾(如 MailerInterface)。这样虽然名称略长,但在使用时不会产生混淆。它们的目的清晰明确,一目了然。如果有必要的话,不要害怕给你的类起长名字,这对它们的理解很有帮助。AbstractWebDeveloperConsoleStreamWrapperExtension 作为一个类名可能看起来很长,但在项目上下文中,它的用途一目了然,无需多问。同样,利用集成开发环境的自动完成功能,只需键入前几个字母,就能在几秒钟内使用它。属性和方法名称也是如此。要明确。
谈到属性和方法的命名,我们倾向于使用 camelCase 命名方式。其原则与 PascalCase 相同(即在每个单词的开头加上一个大写字母),只是名称的第一个字母为小写(例如,myGreatMethod)。有些语言使用 PascalCase 来命名方法,如 C#。老实说,这样做并没有真正的理由或论据,两种命名方式实际上是平等的。就这一次而言,这实际上是一种约定俗成的习惯—一种特定语言的习惯。
命名文件夹
文件夹的命名规则与文件的命名规则类似。文件夹大多使用 PascalCase。其它命名方式也可用于公开文件夹,如网络资源。在创建大型树形结构并赋予其意义时,不应犹豫不决。因此,应避免将文件夹简单命名为 Manager
、Service
或 Wrapper
。这些术语过于笼统,不容易理解其定义。我们倾向于使用更明确的变体,如 Mail 及其子文件夹 Provider、Logger 等。这些子文件夹可以有更通用的名称,它们包含在一个文件夹中,该文件夹的名称定义了一个上下文:域。一种巧妙的方法是使用文件夹将源代码分隔成不同的域。这样,你的应用程序就能得到更好的切分,架构也会更加清晰。与同一主题相关的内容都会放在同一个地方。当这种习惯成为自然时,你的效率将大大提高。许多开源项目和库都使用这种方式来切分源代码。因此,你不仅能浏览自己的代码,还能浏览他人的代码。有时,为一个元素(无论是类、文件、变量还是其它任何元素)找到正确的名称会非常复杂和耗时。然而,这一步尤为重要,不容忽视。注意不要对自己说 "我起的名字不一定很清楚,但我以后会改的"。你很可能会忘记这一点,技术债务就会在不知不觉中产生。