首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Ruby:数据库认证模块

Ruby:数据库认证模块
EN

Code Review用户
提问于 2020-09-10 13:21:58
回答 1查看 56关注 0票数 1

我已经创建了一个模块来验证针对不同数据库的凭据。

代码语言:javascript
复制
module Authentication

  DATABASES = %w[mysql mssql oracle].freeze

  DATABASES.each do |database|
    define_method("#{database}_connect") do |args|
      client = case database
               when 'mysql' then Mysql2::Client.new args.merge(ssl_mode: :disabled)
               when 'mssql' then TinyTds::Client.new args
               when 'oracle' then OCI8.new(args[:username], args[:password], "//#{args[:host]}:#{args[:port]}/#{args[:service_name]}")
               end
      case database
      when 'mysql', 'oracle' then true
      when 'mssql' then client.active?
      end
    end
  end

  def database_authentication_success?(database:, host:, port:, service_name:, username:, password:)
    options = {host: host, port: port, service_name: service_name, username: username, password: password}
    case database
    when 'mysql' then mysql_connect(options)
    when 'mssql' then mssql_connect(options)
    when 'oracle' then oracle_connect(options)
    end
  end
end

请告诉我,怎样才能改进呢?

EN

回答 1

Code Review用户

发布于 2020-09-10 14:19:52

这个模块的用例和原理是什么?我能看出它的作用,但我很难理解为什么我要这么做。

事实上,您有三个几乎相同的case语句来驱动这种行为,这是一种“代码气味”。在大多数其他OO语言中,您可以使用继承或接口以及工厂方法来确定要创建的对象的哪个子类(使用单个case语句)。在这种情况下,目的是抽象出连接到接口后面的数据库之间的区别(这似乎是您在方法database_authentication_success?中要做的)。但是元编程代码会生成明确命名的方法,用于连接到每种类型的数据库,这似乎正好相反,这使得使用起来更加困难。

票数 1
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/249154

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档