【问题标题】:Reflection: for frameworks only?反思:仅适用于框架?
【发布时间】:2010-10-22 21:22:05
【问题描述】:

曾经与我一起工作并尊重的人曾对我说,在应用程序代码中不需要使用反射,它应该只在框架中使用。他说的是 J2EE 背景,而我在该平台的专业经验通常证明了这一点。尽管我曾经使用 Java 编写过一次或两次反射应用程序代码。

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

  • 您是否同意反射仅适用于框架的观点?我很想听听您的意见和经验。

【问题讨论】:

    标签: reflection metaprogramming


    【解决方案1】:

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

    由于随着项目的发展,您的需求往往会变得更加复杂,因此您通常最终会发现静态类型对象系统中的常见习语最终会碰壁。有时寻求反思是最好的解决方案。

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

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

    【讨论】:

    • 这将是 Greenspun 的第 10 条规则“任何足够复杂的 C 或 Fortran 程序都包含一个临时的、非正式指定的、漏洞百出的、一半 Common Lisp 的缓慢实现”
    • 我就知道是这样的 :)
    【解决方案2】:

    反射使 DRY 变得更容易。不用反射也可以写出 DRY 代码,但通常要冗长得多。

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

    听起来他是在专门谈论 Java。在这种情况下,他只是引用了一个特例:在 Java 中,反射是如此的不稳定,它几乎从来都不是做某事的最简单方法。 :-) 如您所见,在 Ruby 等其他语言中,通常是这样。

    【讨论】:

      【解决方案3】:

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

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

      反射可能很有用,但它比执行常规方法调用要慢。看到这个reflection comparison

      【讨论】:

        【解决方案4】:

        Java 中的反射通常不是必需的。这可能是解决某个问题的最快方法,但我宁愿解决导致您认为在应用程序代码中必要的潜在问题。我相信这一点,因为它经常将错误从编译时推送到运行时,这对于足够大的软件来说总是一件坏事,以至于测试并非易事。

        【讨论】:

          【解决方案5】:

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

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

          【讨论】:

            【解决方案6】:

            我不同意,反射在应用程序代码中非常有用,我发现自己经常使用它。最近,我不得不使用反射仅从程序集的路径加载程序集(以调查其公共类型)。

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

            What is reflection and why is it useful?

            【讨论】:

              【解决方案7】:

              别无他法时使用反射!这是性能问题!

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

              看到这个:.NET reflection - performance

              MSDN 有一篇关于When Should You Use Reflection? 的不错的文章

              【讨论】:

                【解决方案8】:

                如果您的问题最好通过使用反射来解决,那么您应该使用它。

                (请注意,“最佳”的定义是从经验中学到的:)

                框架与应用程序的定义也不是非黑即白。有时,您的应用需要一些框架才能做好它的工作。

                【讨论】:

                  【解决方案9】:

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

                  就某些代码的耦合程度而言,通过反射连接的代码与它们的耦合程度一样松散。

                  因此,通过反射完成它的工作的代码可以很高兴地完成它在生活中的角色,而对正在使用它的代码一无所知。

                  【讨论】:

                    猜你喜欢
                    • 2019-11-15
                    • 1970-01-01
                    • 2022-01-22
                    • 2019-05-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    相关资源
                    最近更新 更多