Skip to content

009 — 设计决策

在本文档中,我们列出了 Yii3 开发过程中做出的重要设计决策。

移除魔术属性

Yii 2 中的魔术属性是一个有趣的想法,它允许开发者从公共属性开始,然后无缝迁移到通过魔术方法调用的 getter/setter,而无需更改代码。

在 Yii 3 中移除它的主要原因是它导致到处使用公共属性,从而缺乏封装性和代码脆弱性。

移除服务定位器

Yii 1 和 Yii 2 中的服务定位器很方便,但也被大量滥用。尽管 Yii 2 中提供了依赖注入容器,但服务定位器通常更受欢迎,这导致了对服务定位器本身的依赖、高耦合和难以测试的代码。

Yii 3 仅依赖依赖注入,显著降低了耦合度,使代码更易于测试。

提取通用包

Yii 1 和 Yii 2 是完全封闭的社区。我们拥有的所有代码在 Yii 之外都没有用处,而大多数“外部”代码在没有包装器的情况下在 Yii 中也没有用处。Yii 外部的社区多次指出,Yii 的许多部分设计良好且独特,如果这些部分作为独立包提供,他们会使用它们。

作为 Yii 3 的一部分,缓存、RBAC、视图等包被提取为独立于框架的包。好处是:

  • 增加使用和贡献
  • Yii 团队可以委托维护
  • 可以独立发布

采用 PSR

团队在 Yii 2 中采用了一些 PSR,例如 PSR-4 和 PSR-2。尽管 Yii 是 PHP-FIG 的一部分,但通常没有采用接口。主要是因为当 Yii 2 发布时,这些要么正在制定中,要么还没有被充分采用。

Yii3 从 PSR 中受益,因为现在有许多可以通过 Composer 获得的即用型库:缓存后端、中间件、日志记录器、DI 容器等。

通过在通用包中实现 PSR,我们允许这些包在更多项目中使用,从而提高贡献水平。

改进 DI 容器

Yii 2 容器的问题在于它是为与 Yii 2 组件一起使用而定制的。API 设计不适合与通用 PHP 类一起使用。

在 Yii3 中,我们确保容器可以方便地配置任何 PHP 类。

这应该会导致不再需要 Yii 特定的包装器包,并更直接地使用 Composer 包。

采用严格类型

引入严格类型是因为:

  • PHP 7 现在已成为主流
  • 虽然它们没有解决 Yii 2 的重大问题,但它们有助于避免许多日常开发问题

采用 SemVer

Yii 2 有自己的版本策略。问题:

  • 它不是标准的
  • Composer 依赖于 SemVer
  • 如果版本策略不严格,很难支持建立在包之上的框架

防止验证器改变数据

在 Yii 1 和 Yii 2 中,诸如“date”之类的验证器会改变数据。对于最初不打算改变其验证的数据的验证过程来说,这令人困惑。

查看相关讨论