0

我创建了小型 API 库,一切正常,直到我意识到我需要多个配置。

它看起来像这样:

module Store
  class Api
    class << self
      attr_accessor :configuration

      def configure
        self.configuration ||= Configuration.new
        yield configuration
      end

      def get options = {}
        url = "#{configuration.domain}/#{options[:resource]}"
        # ResClient url ...
      end
    end
  end

  class Configuration
    attr_accessor :domain

    def initialize options = {}
      @domain = options[:domain]
    end
  end

  class Product
    def self.get
      sleep 5
      Api.get resource: 'products'
    end
  end
end

当我同时运行它时,它会覆盖模块配置。

Thread.new do
  10.times do 
    Store::Api.configure do |c|
      c.domain = "apple2.com"
    end
    p Store::Product.get
  end
end

10.times do 
  Store::Api.configure do |c|
    c.domain = "apple.com"
  end
  p Store::Product.get
end

我不知道如何使这个模块更好。感谢您的意见

4

1 回答 1

1

好吧,如果您不希望多个线程竞争一个资源,那么您不应该将其设为单例。尝试将对象配置从类移动到其实例,然后分别实例化和配置它们。

这里还有更多要重构的内容,但这可以解决您的问题:

module Store
  class API
    attr_reader :domain

    def initialize(options = {})
      @domain = options[:domain]
    end

    def products
      sleep 5
      get resource: 'products'
    end

    private

    def get(options = {})
      url = "#{configuration.domain}/#{options[:resource]}"
      # ResClient url ...
    end
  end
end

Thread.new do
  10.times do 
    api = Store::API.new(domain: 'apple2.com')
    p api.products
  end
end

10.times do 
  api = Store::API.new(domain: 'apple.com')
  p api.products
end
于 2013-09-22T23:27:17.587 回答