Как рефакторировать вложенные методы в ruby - PullRequest
0 голосов
/ 05 сентября 2018

У меня большая база ингредиентов. Я использую пользовательские классы для создания ингредиентов и их названий. OilSeed является одним из таких классов.

Существует 64 варианта наименования для следующих масличных семян:

@oil_seed = OilSeed.new(
  common_name: "canola",
  genus: "brassica",
  species: ["capestris", "napus", "rapa", "rapa oleifera", "napus oleifera", "capestris oleifera"],
  oil_types: ["oil"],
  oil_derivatives: ["seed"],
  other_names: ["rapeseed", "polish canola", "rape"],
)

Класс содержит различные методы, используемые для создания вариантов именования. Почти все методы имеют несколько уровней вложенных вызовов .each. Следующий самый сложный. (Обратите внимание, что create_name - это просто вызов метода чего-то, что фактически создает ингредиент в базе данных).

def full_names(alt_names)
  alt_names.each do |alt_name|
    @oil_types.each do |oil_type|
      create_name("#{oil_type} of #{alt_name}")
      create_name("#{alt_name} #{oil_type}")

      @oil_derivatives.each do |oil_derivative|
        create_name("#{alt_name} #{oil_derivative} #{oil_type}")
      end
    end

    @scientific_names.each do |sn|
      @oil_types.each do |oil_type|
        create_name("#{scientific_names} (#{alt_name}) #{oil_type}")

        @oil_derivatives.each do |oil_derivative|
          create_name("#{scientific_names} (#{alt_name}) #{oil_derivative} #{oil_type}")
        end
      end
    end
  end
end

Этот метод генерирует следующие варианты имен для семян common_name и каждого из атрибутов other_names.

  • масло канолы
  • рапсовое масло
  • рапсовое масло
  • масло капусты капусты (канолы)
  • масло семян капусты капусты (канолы)

Мой код работает нормально, но я хотел получить совет о том, должен ли я (или могу ли я) провести рефакторинг сложного метода именования. Во-первых, потому что трудно сказать, что именно происходит. И, во-вторых, хлопотно добавлять новые атрибуты в класс OilSeed. Каждый раз, когда мне нужно добавить один, он создает массу новых each вызовов, которые трудно поддерживать.

РЕДАКТИРОВАТЬ: рефакторинг

def full_names(alt_names)
  combinations = generate_combinations(alt_names, @oil_types, @oil_derivatives)
  names = []

  combinations.each do |sn, ot, od|
    names << "#{sn} #{ot}"
    names << "#{sn} #{od} #{ot}"
  end

  create_names(names)
end

def generate_combinations(bases, *components)
  bases.flatten.product(*components)
end

def create_names(names)
  names.uniq.each { |x| create_name(x) }
end
...