在一堆机架式应用程序/中间件之间共享对象的最佳/最优雅方式?

时间:2011-04-01 19:09:06

标签: ruby sinatra rack

在机架安装的应用程序/中间件之间共享对象的最佳习惯是什么?

例如,这个config.ru有两个映射到不同端点的Sinatra应用程序:

class App1 < Sinatra::Base
  # ...
end

class App2 < Sinatra::Base
  # ...
end

map '/app1' do
  run App1
end

map '/app2' do
  run App2
end

现在,如果这两个应用程序需要共享一个对象,无论是数据库连接器还是其他任何对象,那么最好的成语是什么呢?

我基本上看到两个选项:

1-在config.ru级别创建一个常量,并在应用程序中简单地引用该常量。例如:

SHARED_OBJECT = "hello world"

class App1 < Sinatra::Base
  get '/' do
    SHARED_OBJECT
  end
end

class App2 < Sinatra::Base
  get '/' do
    SHARED_OBJECT
  end
end

map '/app1' do
  run App1
end

map '/app2' do
  run App2
end

2-在config.ru级别创建单个对象并在应用程序中使用它。例如:

class SharedObject
  include Singleton

  def test
    @test ||= "hello world"
  end
end

class App1 < Sinatra::Base
  get '/' do
    SharedObject.instance.test
  end
end

class App2 < Sinatra::Base
  get '/' do
    SharedObject.instance.test
  end
end

map '/app1' do
  run App1
end

map '/app2' do
  run App2
end

评论/建议?
科林

1 个答案:

答案 0 :(得分:5)

我会将共享对象移动到一个单独的文件中并命名它。如果它是数据库连接对象,它可能如下所示:

# config.ru:
require 'lib/my_app/database'
...
class App1 < Sinatra::Base
  get '/' do
    MyApp::Database.with_connection do |conn|
      ...
    end
  end
end

# lib/my_app/database:
module MyApp
  module Database
    def self.with_connection(&block)
      ...
    end
  end
end

我认为这有几个好处:

  1. 它减少了config.ru文件的大小,提高了可读性
  2. 它区分了关注点 - config.ru是关于Rack应用程序的; lib/my_app/database.rb是关于数据库的
  3. 它使提取更容易。在某些时候,您可能希望将App1和App2分离为单独的项目,并将数据库连接包含为gem。当数据库代码位于自己的模块和文件中时,这很容易。
  4. Phrogz关于常数足够且不需要单身人士的评论是明智的。