用脚本应对业务不清析的情况 (2)

用脚本应对业务不清析的情况

  之后,就可以使用XML配置将Messenger bean注入到应用程序的类中。由于AOP的帮助,在Bean对应的脚本文件发生变化时,这个Bean可以自动“刷新”。

  这种方法看起来不错,但是作为开发人员,如果想充分发挥动态语言的威力,应该为bean实现完整的类。在现实中,脚本可能是纯函数,因此需要在脚本中添加一些额外的代码使其与Spring兼容。此外,现在一些开发人员认为XML配置与注解相比,已经“过时”,并且尽量避免使用它,因为会觉得bean的定义和注入分散在Java代码和XML代码中。虽然这更像是审美问题而不是性能/兼容性/可读性等问题,但我们也许会把它考虑在内。

脚本:挑战和想法

  任何事情都有代价,当为应用程序添加脚本支持功能时,可能会遇到一些挑战:

可管理性 - 通常脚本分散在应用程序中,因此管理大量的evaluateGroovy(或类似的)调用会很困难。

可发现性 - 如果在调用的脚本中出现问题,很难在源代码中找到实际的出错点。但是在IDE中能很轻松地找到所有脚本调用点。

透明度 - 编写脚本扩展并非是一件简单的事情,因为没有关于要传递给脚本的变量的信息,也没有关于脚本返回的结果的信息。最终,脚本只能由开发人员通过查看源代码完成。

更新 - 部署(更新)新脚本总是存在危险性,在用于生产环境之后很难进行回滚。

  将对脚本方法的调用隐藏在常规Java方法下似乎可以解决大部分这种问题。更好的方法是注入“脚本化”bean并使用有意义的名称调用其方法,而不是从通用类中调用另一个“eval”方法。这样,我们的代码将可以自描述,开发人员不需要查看文件“disc_10_cl.groovy”来确定参数名称、类型等。

  另一个优点 - 如果所有脚本都有与之关联的唯一java方法,则可以使用IDE中的“Find Usages(查找用例)”功能轻松找到应用程序中的所有扩展点,同时也可以知道此脚本的参数和返回值是什么。

  这种编写脚本的方式也使得测试变得更简单 - 我们不仅可以“像往常一样”测试这些类,而且如果需要也可以使用Mocking框架。

  所有这些都再次提及本文开头提到的方法 - 用于脚本化方法的“特殊”类。如果我们更进一步对开发人员隐藏对脚本引擎的调用、参数创建等操作用会怎么样?

脚本仓库概念

  这个想法很简单,所有使用过Spring框架的开发人员都应该很熟悉。我们只是创建一个java接口,并以某种方式将其方法链接到脚本。举例来说,Spring Data JPA使用的就是类似的方法,其中接口方法基于其名称转换为SQL查询,然后由ORM引擎执行。

  实现这个概念可能需要什么?

  可能需要一个类级别的注解来帮助我们检测脚本仓库接口并为它们构造一个特殊的Spring bean。

  还有一个方法级别的注解,可以帮助我们将方法链接到具体的脚本实现。

  如果给接口方法提供一个默认实现,这个实现不是简单的存根,而是一部分有效的业务逻辑,这样会更好。这样的话,在业务分析人员实现算法之前可以一直使用这个默认实现。或者我们可以让他/她(业务专家)自己来编写这个脚本 :-)。

  假设需要创建根据用户的个人资料计算折扣的服务。业务分析师表示,我们可以安全地假设默认情况下可以为所有注册客户提供10%的折扣。对于这种情况,我们可能会考虑以下概念代码:

用脚本应对业务不清析的情况

  当有了合适的折扣算法实现时,groovy脚本可以这样写:

用脚本应对业务不清析的情况

  这一切的最终目标是让开发人员只实现一个接口和折扣算法脚本,并且不需要笨拙地调用那些 “getEngine” 和 “eval”方法。脚本解决方案应处理所有的逻辑:当方法被调用时拦截调用,查找并加载脚本文本,执行它并返回结果(如果没找到脚本文本,则执行默认方法)。理想的用法大概如下:

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zypzds.html