避免幻数而不创建依赖项


Avoiding magic numbers without creating dependencies

我正在为我正在开发的API创建一个错误管理器。其想法是,它提供了一个可以从API返回的错误代码存储区,以确保以相同的方式处理不同调用中的同一错误(例如,请求中缺少所需的值)。

我最初的做法是:

$this->_errorManager->setError(ErrorCodes::REQUIRED_FIELD);

然而,这会在我想设置错误的任何地方创建对错误代码类的依赖关系。

替代方案是:

$this->_errorManager->setError(100);

但现在我的代码中间有一个数字,它毫无意义。

虽然我能想到这个特定问题的解决方案,但在其他情况下,我会想使用"enum",而且我想不出不将类紧密耦合的解决方案。

有没有更好的方法或不同的方法可以去除幻数?还是紧密耦合是我必须接受并根据具体情况进行考虑的事情?

这是所需的耦合。虽然让应用程序和它的错误管理器松散耦合是个好主意,但没有理由将应用程序及其错误代码分离,因为它们属于一起

依赖项:

+-----------------------+
|Application error codes|<------------+
+-----------------------+             |
           ^                          |
           |                          |
+----------+----------+               |
|Application component|               |
+----------+----------+               |
           |                          |
           v                          |
+-----------------------+     +-------+-----+
|Error handler interface|<|---+Error handler|
+-----------------------+     +-------------+

您可以通过"预处理器"宏和makefile清除这些障碍。预处理器宏是m4提供的。

假设您维护了一个错误代码文件,如下所示。

   define(`ERR_REQUIRED_FIELD',`100')dnl

然后,您可以编写带有英文错误"constant"的PHP代码。

$this->_errorManager->setError(ERR_REQUIRED_FIELD);

并在makefile中包含一行,该行通过m4运行这两个文件。有不止一种方法可以做到这一点。(为了简洁起见,我省略了makefile,只是通过m4运行我的测试文件。)

$ m4 test.php.m4 > test.php
$ cat test.php
$this->_errorManager->setError(100);

确实引入了依赖项;php文件将全部取决于错误代码的文件。但这是一个微不足道的依赖项,可以通过makefile轻松管理。在实践中,我可能会构建一个错误代码文件,看起来像这样。

ERR_DISK_FULL
ERR_REQUIRED_FIELD
ERR_MISSING_ARG

并使用文本实用程序和make

  • 构建m4宏定义,或者
  • 为ErrorCodes模块构建定义

数值等于行号;这保证了您永远不会有重复的错误代码。