转载

浅析annotations

前言

Java 中,我们可以大量看到 annotations 的使用,并且, annotations 也从底层得到了支持。而对于 PHP 而言,我们可以在一些项目中看到 annotations 的使用,但是众多 package 还是在 语言层面 实现(通过解析注释+反射的方式)。

当然,其实在 PHP RFC 中也有提案,文中也阐述了从底层实现 annotations 的必要性:

Frameworks in general rely on metadata information in order to correctly work. They can use it for many purposes:

phpUnit Providing meta functionality for test cases, examples: @dataProvider for test data iteration, @expectedException for catching exceptions, etc.

Doctrine For Object-Relational mapping, examples: @Entity, @OneToOne, @Id, etc.

Zend Framework Server classes Used to automate mappings for XML-RPC, SOAP, etc.

TYPO3 for dependency injection and validation

Symfony2 for routing rules

Others One clear thing that comes to my mind is Validation, Functional Behavior injection (which could take advantage of Traits), etc. Also, any Framework could take advantage of it somehow.

So, any meta mapping injection could be easily achieved via the implementation of a centralized Annotations support.

The .NET framework uses Data Annotation: http://www.asp.net/mvc/tutorials/validation-with-the-data-annotation-validators-cs

An advantage here is the .net framework will process some annotations and inject behavior into the compiled source code.

It's important to note that annotations exist in java and .net but many strong use cases exist in these languages to provide hints to the compiler (@NotNull).

These types of use cases (hints to the Zend lexer/parser or other PHP implementations) are not presented in this RFC.

但是令人遗憾的是,这个议案到现在还没有通过。不过我认为我们应该思考的是,我们为什么需要在语言中实现这样的 featrue ?需要说明的是,此文并非告诉你应该如何去使用某些 annotations 包的说明文,它仅仅只是我对 annotations 的一些思考和浅析。坦率地讲,我使用的的确不多,如有不对还望指正。

优点

其实正如上文所提到的议案所诉,最大的优点在于,当我们在使用 annotations 时, annotations 寄希望于我们能在一个元数据的颗粒上去完成我们的业务代码。比如当我们在面对一个 action 时,我们能很清晰的了解到这个 action 的整体运行过程: HTTP METHOD 是什么,需要哪些具体的参数,参数的类型是什么,返回 template 模板是什么等等。

此外,当我们在使用一些测试案例时,我们能够很方便的去检测对应的参数以及相关返回数据。

总的来说,使用 annotations 让代码从更小颗粒的范畴来说可读性更强,同时,对于测试而言更加友好,我们也无需在业务代码层面做检测的操作。

缺点

但是,一旦我们把我们的配置分散到不同的文件中,这便意味着,我们必须有一个约定俗成的规则,才能减少团队每个成员对于 annotations 在项目上的具体使用。举例说明就是,比如我们在做「收藏」功能时,我们为了保证代码的简约和便于维护,往往会单独抽出一个 收藏类 来统一维护收藏相关的代码,那么问题来了,当我们面对一个例如 /api/articles/{id}/collect 的接口时,我们应该第一时间在 article 类去找还是在 collection 类里面去找呢?同时,对于我们要找到具体的 action 也增添了为数不多的工作。而这似乎又从较大的一个颗粒上来说减少了我们代码的可读性。

同时,在实现上,并没有像 Java 一样通过字节码的方式实现无疑给我们项目的运行增加了负担。

综上所述,这可能也是 Laravel 并没有使用 annotations 的原因所在吧。

后言

后来我也找朋友聊过这个话题,他虽然没有给我一个非常清晰的回复,不过从他言论中可以看到的是,在现代化的编程中,使用 annotations 去替代 xml 似乎是一个理所应当的事情。

虽然 annotations 就像一把双刃剑,但是我还是期待 annotations 真正加入 PHP 的一天,我想那时候应该会给我们的代码编写增加不少乐趣吧。

本文由nine 创作,采用 知识共享署名4.0 国际许可协议进行许可

本站文章除注明转载/出处外,均为本站原创或翻译,转载前请务必署名

最后编辑时间为: Jul 16, 2018 at 06:05 pm

原文  https://www.hellonine.top/index.php/archives/102/
正文到此结束
Loading...