用于在rails应用程序中实现插件的设计模式

时间:2015-01-21 22:38:01

标签: ruby-on-rails design-patterns plugins

我正在编写一个rails应用程序,它必须允许第三方创建为我的应用程序添加服务支持的插件(即gems)。这些插件都将实现相同的方法。

我读过这样做的最佳方法是使用单表继承(STI),将所有逻辑保留在模型子类中并远离控制器。

这方面的一个例子是指标仪表板应用程序,它使用Pingdom插件将最近的网站响应时间添加到图表中。该插件将添加一个Pingdom子类,扩展Metric模型,实现run方法。应用程序将在运行每个插件的run方法的任务中调用此方法。

制作基于插件的应用程序的正确方法是什么?它应该使用所有逻辑的模型吗?还有更好的方法吗?

3 个答案:

答案 0 :(得分:1)

确保单表继承在此实例中很有用。

# /app/models/user.rb
class User < ActiveRecord::Base
  # define your base methods, variables and constants
end
# /app/models/pluginuser.rb
class PluginUser < User
  # The gem builders can extend your methods, variables and constants or define their own
end

有一点需要注意的是,所有插件代码都将在同一名称空间中运行。插件一可以从插件二调用子类方法。这是一项要求吗?

答案 1 :(得分:1)

只需0.02美元,并且知道将会有有效的替代答案。

我认为我写的宝石是完全独立的服务。这意味着:

  1. 您的代码无法对gem如何处理其功能提出任何要求/假设。它应该把那颗宝石想象成一个黑盒子。
  2. 宝石不能对您的应用程序的其余部分的设计或行为做出任何要求/假设。
  3. 由此产生的逻辑后果是,您的应用程序及其gem应该达成共识的事物是常见的API - 它们的gem命令将哪些数据作为输入以及它们如何响应。

    因此,你可以向正在构建新宝石的人提出这些请求似乎是合理的(你可以根据需要更改方法名称等):

    • 任何构建的gem都应该有一个命令调用run!,它接受​​一组对你有意义的规范/模式的参数。
    • 该gem必须从该命令返回一个响应对象,该响应对象响应方法的常见 set ,例如success?bodyerrors

    但是,您决定保留该数据,操纵该数据等需要由您的应用程序负责处理。 gem不应该对你的应用程序数据库模式,它如何处理持久性等做出假设。这种方法可能会有一段时间,但不可避免地会出现大问题并且成为放松的噩梦。

    如果您对我喜欢这种方法的原因有任何疑问,或者想讨论任何其他方法,请告知我们。

    编辑:

    我想补充一点,上述建议是基于您在评论中提供的条件,通过安装宝石来实现此功能。我应该澄清,这种情况有很多与之相关的安全风险(以及其他问题)。

    您可能更好地构建功能,允许以可能构建应用程序功能的方式编写附加组件/扩展,但实际上不会与应用程序的代码交互。

    如果您查看如何为Heroku(https://devcenter.heroku.com/articles/building-a-heroku-add-on)构建加载项或如何构建Chrome扩展程序(https://developer.chrome.com/extensions/getstarted),您可以看到应用程序和扩展程序的关注点是完全分开的。

答案 2 :(得分:0)

为什么不将插件实现为通过http服务调用的微服务?例如,插件需要实现像/data这样的单个端点,根据用户调用标准参数。如果您需要安全性,可以加密用户凭据。

优点:

  • 您不必审核添加为宝石的代码(我不相信,我甚至不相信代码审核)
  • 插件提供商不必使用ruby
  • 您可以更改插件,而无需再次部署整个应用程序。
  • Beta插件将免费提供给heroku。

heroku博客上有一篇很棒的文章: