在Nette 4中I-前缀从接口名称中消失的原因

124 阅读3分钟

在Nette中,接口是以字母I 开始命名的(例如:IRequest )。几年前,一个极其缓慢和长期的过程开始了,它在保持向后兼容性的同时,悄悄地摆脱了这些前缀。这到底是怎么发生的,为什么?

我们周围的约定

Nette从一开始就采用了用字母I 作为接口前缀的惯例。它从来没有在抽象类的名称上做过任何区分。在其他框架(如Symfony、CakePHP、Zend或PSR)中,你可能会看到不同的约定,使用Interface 后缀(如:Psr\Cache\CacheItemInterface )和抽象类的Abstract 前缀(如:Psr\Log\AbstractLogger )。最后,有些库(例如Laravel或PHP系统库)不以任何方式区分接口或抽象类(例如:ThrowableIterator接口,或抽象类FilterIterator )。

如果我们把目光投向PHP世界之外,例如C#就使用了I 前缀,而在Java或TypeScript中,这些名称是没有区别的。

大约十年前,当Nette DI--所有现代简洁设计的应用程序的核心--创建时,我完全意识到区分接口和抽象类,无论是用前缀还是后缀,都是一个巨大的错误。但是在那个时候,这个框架已经有5年的历史了,不可能在不引起巨大的BC破坏的情况下改变接口的名称。为了保持一致性,我在Nette中继续使用前缀,但在所有其他项目中放弃了。(当时Nette仍然是一个单体,但例如Nette Tester是一个独立的项目,你不会在那里找到接口的前缀)。

然而,我仍然在寻找一种方法来不费吹灰之力地放弃I的前缀。我认为接口名称的区分是一个重大的错误,值得花大力气去纠正它。特别是由于该框架被程序员当作简洁设计的典范。

原因是另一篇文章《前缀和后缀不属于界面名称》的主题。

如何告别 "I "的名字?

几年后,我找到了一种方法,将I 。悄悄地,而且是完全兼容的。这是一个提前多年计划的过程,从Nette 3.1的发布开始。

通常情况下,只需简单地重命名原始界面(例如:Nette\Mail\IMailerMailer ),同时创建一个别名(IMailer ),使两个版本都能使用。与此同时,我在源文件中加入了只有IDE和Composer可以看到的 "隐藏 "代码。它使自动加载对别名也起作用,并迫使编辑器在代码中把它列为废弃的,并注明应使用无前缀的版本。这样,所有现有的代码都能保持不变,而程序员则被引导去选择新的版本。

在某些情况下,我没有重命名接口,因为计划要改变它(例如,新的Nette\Security\UserStorage 与旧的Nette\Security\IUserStorage 不同,作为过渡的一部分,两者可以同时使用),或者因为我正在计划一个不同的解决方案(例如,Tracy\IBarPanel )。

在某些情况下,删除前缀是不可能的,因为这个名字已经被占用了。例如Nette\Security\IIdentityIdentity 的情况。在这里,SimpleIdentity 需要先作为Identity 的继任者,而这个名字将被释放。这样的事情必须在几个主要的版本中进行,因此需要很多年才能真正做到无痛。但是并不急于求成。

所以在Nette 4中,只有Nette\Http\IRequestIResponse 将保留前缀,作为对以前的提醒。还有Nette\ComponentModel\IComponentIContainer ,但我不确定它们的存在是否有用。当然,别名将继续发挥作用。