遵循基本原则,构建程序的首选方法及其数据可以变化,但用于实现相同的标准"任务?它应该很容易扩展,以包括更多的提供者。
例如:
require 'mechanize'
require 'open-uri'
class AccountFetcher
@@providers = {}
@@providers['provider_a'] = [
'http://url_for_login_form.com/', 'name_of_form',
# the number of fields can vary between different providers
[ ['name_of_field', 'value_for_it'], ['another_field', 'another_value'] ],
['name for username field', 'name for password field']
]
@@providers['provider_b'] = [
'http://another_url.com/', 'another_form_name',
[
# array of more fields that are specific to this form
],
['name for username field', 'name for password field']
]
# looks more nice using AccountFetcher.accounts opposed to @@accounts
def self.accounts
@@providers
end
# example of a method that uses information that can vary
def self.fetch_form(agent, account_type)
# the first element in the array will always be the url
page = agent.get(AccountFetcher.accounts[account_type][0])
# the second element in the array will always be the name of the form
form = page.form(AccountFetcher.accounts[account_type][1])
end
def self.initialize_form(agent, account_type)
form = AccountFetcher.fetch_form(agent, account_type)
# will cycle through all fields that require 'pre-filling'
AccountFetcher.accounts[account_type][2].each do |f|
# f[0] will always be the name of the field and f[1] will
# always be the value for the field; however, the amount of
# fields may vary
form.field_with(:name => f[0]).value = f[1]
end
form
end
所以一般的想法是使用一个由散列组成的类变量,并且包含包含相应数据元素的数组。我需要为每个具有类似功能的类执行此操作。
我的另一个想法是替换类变量,而是将每个提供程序转换为可由其他类访问的类数据库。所以provider_a
会变成:
class ProviderA
# all the possible information needed
# methods will have similar names across all the different providers
end
可以选择合适的提供者
class Providers
@@p_providers = {}
@@p_providers['provider a'] = ProviderA.new
@@p_providers['provider b'] = ProviderB.new
@@p_providers['provider c'] = ProviderC.new
@@p_providers['provider d'] = ProviderD.new
def self.return_provider(name)
@@p_providers[name]
end
end
前者或后者的解决方案更合适吗?或者是否有更多的红宝石'解?
答案 0 :(得分:1)
I would store this configuration values in an external YAML file. Your configuration file could looke like this:
# config/providers.yaml
provider_a:
url: 'http://url_for_login_form.com/'
name: 'name_of_form'
fields:
- name: 'name_of_field'
value: 'value_for_it'
- name: 'another_field'
value: 'another_value'
provider_b:
url: 'http://...'
...
You could load that file with YAML.file_file
that returns nested hash in this example.
require 'yaml'
def AccountFetcher
def self.accounts
@accounts ||= YAML.parse_file("config/providers.yaml")
end
#...
end
You may want to consider using a Gem like has_configuration
that makes handling the data structure a bit easier.