Ruby:如何重构非常相似的类?

时间:2017-03-14 14:00:51

标签: ruby refactoring

我有一堆非常相似的课程。唯一的区别在于类名的一部分,一些pathes以及其他属于同一组的类。

例如,我有一个使用XImporter的XDispatcher和一个使用YImporter的YDispatcher,其中Dispatchers和Importers是相同的,除了名称和任何使用该名称的片段,如pathes,调用其他类的分组。

class XDispatcher
  def initialize
    path = Rails.root.join('x_dispatcher/files')
  end

  def run
    # do stuff
    # importer = XImporter.new()
  end
end

class YDispatcher
  def initialize
    path = Rails.root.join('y_dispatcher/files')
  end

  def run
    # do stuff
    importer = YImporter.new()
  end
end

编辑: 对我感到羞耻..我完全融合了继承和延伸。为了使这个问题有趣,我希望看到一些奇特的东西或实验方法来解决这个问题'。

3 个答案:

答案 0 :(得分:3)

如果唯一的区别是名称,你甚至不应该为继承而烦恼。只需使用名称初始化Dispatcher,然后将其传递到您需要的位置:

class Dispatcher
  def initialize name
    @name = name
    path = Rails.root.join("#{@name}_dispatcher/files")
  end

  def run
    # do stuff
    # importer = Importer.new(@name)
  end
end

Dispatcher.new("x").run
Dispatcher.new("y").run

答案 1 :(得分:2)

也许你可以做这样的事情。

class Dispatcher
  def initialize
    path = Rails.root.join(self.class::RAILS_ROOT_PATH)
  end

  def run
    # do stuff
    importer = self.class::IMPORTER_CLASS.new
    # process
  end
end

class XDispatcher < Dispatcher
  RAILS_ROOT_PATH = 'x_dispatcher/files'
  IMPORTER_CLASS = XImporter
end

class YDispatcher < Dispatcher
  RAILS_ROOT_PATH = 'y_dispatcher/files'
  IMPORTER_CLASS = YImporter
end

答案 2 :(得分:1)

我建议:

class Dispatcher
  class << self
     attr_accessor :file_path, importer_class
  end

  def path 
    @path ||= Rails.root.join(self.class.file_path)
  end

  def importer
    @importer ||= self.class.importer_class.new
  end

  def run
    # do stuff
  end
end

class XDispatcher < Dispatcher
  file_path = 'x_dispatcher/files'
  importer_class = XImporter
end

class YDispatcher < Dispatcher
  file_path = 'y_dispatcher/files'
  importer_class = YImporter
end

两个主要原因:

  1. 它消除了对常量的依赖 - 特别是它们不存在于父类中的问题 - 或者如果它们是,它们在子类中被覆盖
  2. 它消除了对initialize方法的依赖,这种方法需要做的不仅仅是加载初始数据 - in my opinion is bad practice