Computer >> 컴퓨터 >  >> 프로그램 작성 >> Ruby

루비 리팩토링 기법:소개

용어에 익숙하지 않은 경우 리팩토링은 코드가 수행하는 작업을 변경하지 않고 코드의 품질을 개선하는 행위입니다. 이렇게 하면 코드 작업이 훨씬 쉬워집니다.

이 게시물에서는 몇 가지 일반적인 Ruby 리팩토링 기술을 배웁니다.

시작하겠습니다!

추출 방법

가장 일반적인 리팩토링 중 하나는 '추출 방법'으로 알려진 것입니다. 이 리팩토링에서는 이전 메서드에서 새 메서드로 일부 코드를 이동합니다. 이렇게 하면 설명적인 이름을 가진 더 작은 방법을 사용할 수 있습니다.

예를 살펴보겠습니다.

@sold_items = %w( onions garlic potatoes )

def print_report
  puts "*** Sales Report for #{Time.new.strftime("%d/%m/%Y")} ***"
  @sold_items.each { |i| puts i }
  puts "*** End of Sales Report ***"
end

이 방법의 가장 못생긴 부분인 현재 날짜 생성을 추출하는 것으로 시작할 수 있습니다.

def print_report
  puts "*** Sales Report for #{current_date} ***"
  @sold_items.each { |i| puts i }
  puts "*** End of Sales Report ***"
end

def current_date
  Time.new.strftime("%d/%m/%Y")
end

이것은 이미 더 잘 읽히지만 우리는 조금 더 나아갈 수 있습니다. 이 코드로 끝내기 위해 몇 가지 방법을 더 추출해 보겠습니다.

def print_report
  print_header
  print_items
  print_footer
end

def print_header
  puts "*** Sales Report for #{current_date} ***"
end

def current_date
  Time.new.strftime("%d/%m/%Y")
end

def print_items
  @sold_items.each { |i| puts i }
end

def print_footer
  puts "*** End of Sales Report ***"
end

예, 이제 코드가 더 길어졌지만 읽기가 더 쉽지 않습니까? 작은 방법을 두려워하지 마십시오. 코드에 좋습니다.

조건부 리팩토링

복잡한 조건문을 메서드로 리팩토링하여 더 읽기 쉽게 만들 수도 있습니다.

:

def check_temperature
  if temperature > 30 && (Time.now.hour >= 9 && Time.now.hour <= 17)
    air_conditioner.enable!
  end
end

if의 두 번째 부분 문은 가독성이 좋지 않으므로 메서드로 추출해 보겠습니다.

def check_temperature
  if temperature > 30 && working_hours
    air_conditioner.enable!
  end
end

def working_hours
  Time.now.hour >= 9 && Time.now.hour <= 17
end

여기서 우리는 조건을 설명하는 이름을 지정하여 이 코드의 미래 독자(귀하를 포함하여)가 훨씬 쉽게 작업할 수 있도록 했습니다.

메서드 개체로 메서드 바꾸기

때로는 통제할 수 없는 큰 방법이 있습니다. 이 경우 큰 메서드에는 많은 지역 변수가 있는 경향이 있기 때문에 리팩토링하기 어려울 수 있습니다. 한 가지 해결책은 'Method Object' 리팩토링을 사용하는 것입니다.

<블록 인용>

"큰 메서드는 클래스가 숨는 곳입니다." - 밥 삼촌

예를 들어 보겠습니다.

require 'socket'

class MailSender
  def initialize
    @sent_messages = []
  end

  def send_message(msg, recipient = "rubyguides.com")
    raise ArgumentError, "message too small" if msg.size < 5

    formatted_msg = "[New Message] #{msg}"

    TCPSocket.open(recipient, 80) do |socket|
      socket.write(formatted_msg)
    end

    @sent_messages << [msg, recipient]

    puts "Message sent."
  end
end

sender = MailSender.new
sender.send_message("testing")

리팩토링을 수행하기 위해 새 클래스를 만들고 지역 변수를 인스턴스 변수로 승격할 수 있습니다. 이렇게 하면 데이터 전달에 대해 걱정할 필요 없이 이 코드를 추가로 리팩토링할 수 있습니다.

<블록 인용>

여기요! Ruby 기술을 크게 향상하고 싶으십니까? 아름다운 루비 코스를 확인하세요 🙂

MailSender입니다. 리팩토링 후 클래스:

class MailSender
  def initialize
    @sent_messages = []
  end

  def deliver_message(message)
    send(message)
    @sent_messages << message
    puts "Message sent."
  end

  def send(msg)
    TCPSocket.open(msg.recipient, 80) { |socket| socket.write(msg.formatted_msg) }
  end
end

그리고 이것은 우리가 도입한 새로운 클래스입니다:

class Message
  attr_reader :msg, :recipient

  def initialize(msg, recipient = "rubyguides.com")
    raise ArgumentError, "message too small" if msg.size < 5

    @msg       = msg
    @recipient = recipient
  end

  def formatted_msg
    "[New Message] #{msg}"
  end
end

sender = MailSender.new
msg    = Message.new("testing")

sender.deliver_message(msg)

결론

이러한 리팩토링 기술을 사용하면 단일 책임 원칙을 준수하고 클래스와 메서드를 제어하는 ​​데 도움이 됩니다.

이 기사가 재미있었다면 친구들과 공유하여 그들도 즐길 수 있도록 해주세요 🙂