反思:仅限框架?

时间:2009-04-30 15:22:21

标签: reflection metaprogramming

我曾与之合作并尊重的人曾经告诉我,在应用程序代码中不应该使用反射,并且它只应该在框架中使用。他是在J2EE背景下发言的,我在该平台上的专业经验确实能够证明这一点;虽然我已经用Java编写了反思应用程序代码一次或两次。

我对Ruby on Rails的体验完全不同,因为Ruby非常鼓励你编写动态代码。如果没有反射和元编程,Rails为您提供的大部分内容都是不可能的,并且许多相同的技术同样适用于您的应用程序代码。

  • 您是否同意仅反映框架的观点?我很想听听你的意见和经历。

9 个答案:

答案 0 :(得分:2)

有一个古老的笑话,用静态类型语言编写的任何足够复杂的系统都包含一个不完整的,低级的Lisp实现。

由于随着项目的发展,您的需求会变得越来越复杂,您通常最终会发现静态类型对象系统中的常见习语最终会出现问题。有时候进行反思是最好的解决方案。

我对像Ruby这样的动态类型语言和像C#这样的静态类型语言感到高兴,但Ruby中的隐式反射通常会使代码更简单,更容易阅读。 (取决于所需的元编程魔法,有时更难写)。

在C#中,我发现了没有反射就无法解决的问题,因为直到运行时我都没有这些信息。一个例子:当试图操纵一些第三方代码生成在另一个进程中运行的Silverlight对象的代理时,我不得不使用反射来调用特定的强类型“通用”版本的方法,因为编组要求调用者在另一个进程中假设对象的类型是为了从中提取我们需要的数据,并且C#不允许在运行时指定泛型方法调用的“类型”(除了反射)技术)。我想你可以说我们的工具是一种框架,但我很容易想象一个普通应用程序面临类似问题的案例。

答案 1 :(得分:1)

反射让DRY变得更容易。当然可以在没有反射的情况下编写DRY代码,但它通常更加冗长。

如果我的程序中的某些信息以某种方式编码,为什么不会我会使用反射来获取它,如果这是最简单的方法?

听起来他特别是在谈论Java。在这种情况下,他只是引用了一个特殊情况:在Java中,反射是如此不稳定,几乎从来不是最简单的做事方式。 :-)在Ruby等其他语言中,正如你所见,它经常是。

答案 2 :(得分:1)

反射肯定在框架中大量使用,但正确使用可以帮助简化应用程序中的代码。

我之前见过的一个例子是使用大型接口的JDK代理(20多种方法)来包装(即委托)特定的实现。使用InvocationHandler只重写了几个方法,其余的方法都是通过反射调用的。

反射可能很有用,但执行常规方法调用的速度较慢。请参阅此reflection comparison

答案 3 :(得分:1)

通常没有必要在Java中进行反思。这可能是解决某个问题的最快方法,但我宁愿找出导致您认为在应用程序代码中必要的基础问题。我相信这是因为它经常将错误从编译时间推送到运行时间,对于足够大的软件而言,这总是一件坏事,因为测试非常重要。

答案 4 :(得分:0)

我不同意,我的应用程序使用反射来动态创建提供程序。如果逻辑很简单并且不能保证更复杂的模式,我也可以使用反射来控制逻辑流程。

在C#中,我使用反射来获取Enumeration中的属性,这有助于我确定如何向最终用户显示枚举。

答案 5 :(得分:0)

我不同意,反射在应用程序代码中非常有用,我发现自己经常使用它。最近,我不得不使用反射来装配程序集(为了调查它的公共类型),而不仅仅是程序集的路径。

这里表达了关于这个主题的几点意见......

What is reflection and why is it useful?

答案 6 :(得分:0)

没有其他方法时使用反射!这是性能问题!

如果您之前已经研究过.NET性能缺陷,那么正常反射的速度可能并不会让您感到惊讶:与直接访问相比,使用反射重复访问int属性的简单测试被证明是慢1000倍到该属性(比较测量时间的中位数80%的平均值)。

请参阅:.NET reflection - performance

MSDN有一篇关于When Should You Use Reflection?

的非常好的文章

答案 7 :(得分:0)

如果使用反射最好解决问题,则应使用它。

(请注意,“最佳”的定义是经验所学的东西:)

框架与应用程序的定义并非完全是黑色和白色也是。有时你的应用程序需要一些框架来完成它的工作。

答案 8 :(得分:0)

我认为观察到应该不需要在应用程序代码中使用反射,并且它只应该在框架中使用,这或多或少都是正确的。

关于如何耦合某些代码片段的频谱,通过反射连接的代码就像它们来的那样松散耦合。

因此,通过反射来完成它的工作的代码可以非常愉快地实现它在生活中的角色,而不是知道使用它的代码。