简体   繁体   中英

refactoring Control Parameter

I'm using a tool for finding code smells in code called reek and I have a problem with one called 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

warning's content: [

55]:ControlParameter: Board#place_ship is controlled by argument 'orientation

How do I fix this?

'Orientation' is a flag value in place_ship method. Value of 'orientation' is not changing as the code executes. So no need to check it 'ship.length' times.

place_ship has only conditional logic and nothing else. This is unnecessary and the conditional logic can reside outside . You are passing in a flag, that tells the method what path to choose, conditionally . This is the Conditional Coupling smell . Generally do not pass in a conditional parameter to a method. Have 2 different methods for the 2 choices and name them aptly.

You already have aptly named vertical_place_ship and horizontal_place_ship methods. You can refactor it like this.

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

Similarly for horizontal_place_ship method.

Regardless of the tool feedback, looking at your code, the only line that differ between the horizontal & vertical case is whether to increase @rows or @columns. An option could be:

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

I removed the two (identical) methods, and just used the ternary operator ('?') to increase the correct variable after placing each ship part.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM