设置两个实例变量的重构方法

时间:2015-12-09 08:45:41

标签: ruby refactoring

我想知道如何重构这部分代码。我需要知道如何获取插件取决于我的发现方式:

findById: function(employeeId) {
    var employee = _.find(employees, {id: employeeId});
    return $q.when(employee);
}

有更好的方法吗? def plugin return @plugin unless @plugin.nil? @plugin = Plugin.find_by_uid(@plugin_id) if @plugin.nil? @plugin_found_by = :aid @plugin = Plugin.find_by_adid(@plugin_id) else @plugin_found_by = :uid end @plugin end def plugin_found_by plugin @plugin_found_by end 方法似乎非常重复。

4 个答案:

答案 0 :(得分:2)

我假设您的Plugin类方法是构造函数(返回Plugin的新实例)。

使用构造函数创建Plugin的新实例时,应该使@plugin_found_byPlugin实例的实例变量,其值取决于它的创建方式。您还应该在Plugin类中使用getter方法。

class Plugin
  attr_reader :plugin_found_by
  def self.find_by_uid(plugin_id)
    @plugin_found_by = :uid
    ...
  end
  def self.find_by_adid(plugin_id)
    @plugin_found_by = :aid
    ...
  end
end

然后,你在另一个类中的方法是:

def plugin
  @plugin ||= Plugin.find_by_uid(@plugin_id) || Plugin.find_by_adid(@plugin_id)
end
def plugin_found_by
  plugin.plugin_found_by
end

答案 1 :(得分:2)

你可以使用这样的东西。

def plugin_found_by
  plugin unless @plugin_found_by
  @plugin_found_by
end

def plugin
  find_plugin unless @plugin
  @plugin
end

def get_plugin(type = :uid)
  Plugin.send("find_by_#{type}", @plugin_id)
end

def find_plugin
  config = {:uid => :uid, :aid => :adid}
  @plugin_found_by = config.select { |_, m| @plugin = get_plugin(m); !@plugin.nil? }.keys[0]
end

但更好的方法是使用类似的东西

class Plugin
  attr_reader :found_by

  def self.find_by_uid(id)
    @found_by = :uid
    super(id)
  end

  def self.find_by_adid(id)
    @found_by = :aid
    super(id)
  end
end

def plugin_found_by
  plugin unless @plugin
  @plugin.found_by
end

def plugin
  [:uid, :adid].each { |m|
    if @plugin = Plugin.send("find_by_#{m}", @plugin_id)
      return @plugin
    end
  }
end

答案 2 :(得分:2)

这是另一个不显眼的解决方案,它将您表达的行为包装到自己的PluginFinder类中:

class PluginFinder
  FINDER_METHODS = [:uid, :adid]

  def initialize(id)
    @id = id
  end

  def plugin
    @plugin || (find_plugin && @plugin)
  end

  def found_by
    @found_by || (find_plugin && @found_by)
  end

  private

  def find_plugin
    @found_by = FINDER_METHODS.find { |m| find_by(m) }
  end

  def find_by(finder_method)
    @plugin = ::Plugin.send("find_by_#{ finder_method }", @id)
  end
end

使用示例:

finder = PluginFinder.new(1)

plugin = finder.plugin
#=> <Plugin:0x007f7fe5c90dd0>

found_by = finder.found_by
#=> :uid

答案 3 :(得分:1)

如果我们假设您显示的代码不属于Plugin类,并且它属于另一个类Plugin类的客户端,则它有责任缓存{的实例{1}}并保留有关其发现方式的信息,您可以重写Plugin方法,如下所示:

plugin

与其他建议的答案不同,此解决方案不要求您修改 def plugin @plugin, @plugin_found_by = [Plugin.find_by_uid(@plugin_id), :uid] unless @plugin @plugin, @plugin_found_by = [Plugin.find_by_adid(@plugin_id), :aid] unless @plugin @plugin end 类实现