我应该重构这些嵌套的每个块吗?

时间:2017-02-23 16:38:58

标签: ruby refactoring

我想知道是否有办法重构此方法以最小化缩进级别。读完干净的代码之后鲍勃说,一旦方法超过两个级别,就越难理解发生了什么......我不认为这种方法过于复杂,但我认为它可以清理干净看起来更像是一个故事。

这是我的方法

def sync!(xml_document, language_id, status_id, file)
  survey = sync_survey.(xml_document, status_id)
  sync_survey_label.(xml_document, survey.id, language_id, file)

  xml_document.xpath('//page').each do |xml_section|
    section = sync_section.(xml_section, survey.id)
    sync_section_label.(xml_section, section.id, language_id)

    xml_section.xpath('.//question_group').each do |xml_question_group|
      question_group = sync_question_group.(xml_question_group, section.id)
      sync_question_group_label.(xml_question_group, question_group.id, language_id)

      xml_question_group.xpath('.//question').each do |xml_question|
        question = sync_question.(xml_question, question_group.id)
        sync_question_label.(xml_question, question.id, language_id)

        xml_question.xpath('.//answerchoice').each do |xml_choice|
          choice = sync_choice.(xml_choice, question.id)
          sync_choice_label.(xml_choice, choice.id, language_id)
        end
      end
    end
  end

  survey
end

所以,我遍历一个xml并保存到相应的方法。每个调查都有很多部分,其中有许多问题组,其中有许多问题有很多选择。

我知道我可以将每个循环提取到一个方法中但是我仍然会有4个级别的缩进。

我想做点像......

def sync!(xml_document, language_id, status_id, file)
  survey = sync_survey.(xml_document, status_id)
  sync_survey_label.(xml_document, survey.id, language_id, file)
  sync_sections.(xml_document)
  sync_section_labels.(xml_document, language_id)
  sync_question_groups.(xml_document)
  sync_question_group_labels.(xml_document, language_id)
  sync_questions.(xml_document)
  sync_question_labels.(xml_document, language_id)
  sync_choices.(xml_document)
  sync_choice_labels.(xml_document, language_id)

  survey
end

是否有任何想法可以做这样的事情或使这些代码更具可读性?甚至有必要重构它吗?欢迎任何想法。

这是完整的课程

class SurveyBuilder
  attr_reader  :xml_parser, :sync_survey, :sync_survey_label, :sync_section, :sync_section_label, :sync_question, :sync_question_label, :sync_question_group, :sync_question_group_label, :sync_choice, :sync_choice_label

  def initialize
    @sync_survey = SurveyBuilder::Sync::Survey.new
    @sync_survey_label = SurveyBuilder::Sync::SurveyLabel.new
    @sync_section = SurveyBuilder::Sync::Section.new
    @sync_section_label = SurveyBuilder::Sync::SectionLabel.new
    @sync_question = SurveyBuilder::Sync::Question.new
    @sync_question_label = SurveyBuilder::Sync::QuestionLabel.new
    @sync_question_group = SurveyBuilder::Sync::QuestionGroup.new
    @sync_question_group_label = SurveyBuilder::Sync::QuestionGroupLabel.new
    @sync_choice = SurveyBuilder::Sync::Choice.new
    @sync_choice_label = SurveyBuilder::Sync::ChoiceLabel.new
    @xml_parser = SurveyBuilder::XMLParser.new
  end

  def call(file, status_id)
    xml_document = xml_parser.(file)
    language_id = Language.find_by(code: xml_document.xpath('//lang_code').children.first.to_s).id

    survey = sync!(xml_document, language_id, status_id, file)

    survey
  end

private
  def sync!(xml_document, language_id, status_id, file)
    survey = sync_survey.(xml_document, status_id)
    sync_survey_label.(xml_document, survey.id, language_id, file)

    xml_document.xpath('//page').each do |xml_section|
      section = sync_section.(xml_section, survey.id)
      sync_section_label.(xml_section, section.id, language_id)

      xml_section.xpath('.//question_group').each do |xml_question_group|
        question_group = sync_question_group.(xml_question_group, section.id)
        sync_question_group_label.(xml_question_group, question_group.id, language_id)

        xml_question_group.xpath('.//question').each do |xml_question|
          question = sync_question.(xml_question, question_group.id)
          sync_question_label.(xml_question, question.id, language_id)

          xml_question.xpath('.//answerchoice').each do |xml_choice|
            choice = sync_choice.(xml_choice, question.id)
            sync_choice_label.(xml_choice, choice.id, language_id)
          end
        end
      end
    end
    survey
  end

end

0 个答案:

没有答案