Рефакторинг контрольного параметра

Я использую инструмент для поиска запахов кода в коде, называемом reek, и у меня есть проблема с одним из них называется Control Parameter

def place_ship(ship, start_position, orientation)
    @row = start_position[:row]
    @column = start_position[:column]
    ship.length.times do
        if orientation == :vertical
            vertical_place_ship(row,column,ship)
        else
            horizontal_place_ship(row,column,ship)
        end
    end
end

def vertical_place_ship(row,column,ship)
    self.grid[row][column].ship = ship
    self.grid[row][column].status = :occupied
    @row += 1 
end

def horizontal_place_ship(row,column,ship)
    self.grid[row][column].ship = ship
    self.grid[row][column].status = :occupied
    @column += 1
end

содержание предупреждения: [55]:ControlParameter: Board#place_ship управляется ориентацией аргумента

Как лучше всего устранить этот запах?

Заранее спасибо,

Мартин

2 ответа

"Ориентация" - это значение флага в методе place_ship. Значение ориентации не меняется при выполнении кода. Так что нет необходимости проверять его время доставки.

У place_ship есть только условная логика и больше ничего. Это не нужно, и условная логика может находиться снаружи. Вы передаете флаг, который указывает методу, какой путь выбрать условно. Это запах условной муфты. В общем случае не передавайте в метод условный параметр. У 2 разных методов для 2 вариантов и назовите их точно.

У вас уже есть метко названные методы vertical_place_ship и Horizontal_place_ship. Вы можете рефакторинг это так.

def <method_that_calls_place_ship>
// other code
    if orientation == :vertical
      vertical_place_ship(ship, start_position)
    else
      horizontal_place_ship(ship, start_position)
    end
// more code
end

def vertical_place_ship(ship, start_position)
    row = start_position[:row]
    column = start_position[:column]

    ship.length.times do
      self.grid[row][column].ship = ship
      self.grid[row][column].status = :occupied
      row += 1 
    end  
end

Аналогично для метода Horizontal_place_ship.

Независимо от обратной связи с инструментом, глядя на ваш код, единственная строка, которая различается между горизонтальным и вертикальным регистром, - это увеличение @rows или @columns. Вариант может быть:

def place_ship(ship, start_position, orientation)
    row = start_position[:row]
    column = start_position[:column]
    ship.length.times do
        self.grid[row][column].ship = ship
        self.grid[row][column].status = :occupied
        orientation == :vertical ? row += 1 : column += 1
    end
end

Я удалил два (идентичных) метода и просто использовал троичный оператор ('?'), Чтобы увеличить правильную переменную после размещения каждой части корабля.

Другие вопросы по тегам