浅析annotations

in PHP with 1 comment

前言

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的一天,我想那时候应该会给我们的代码编写增加不少乐趣吧。

Responses
  1. 完全不懂 走错了

    Reply