용어에 익숙하지 않은 경우 리팩토링은 코드가 수행하는 작업을 변경하지 않고 코드의 품질을 개선하는 행위입니다. 이렇게 하면 코드 작업이 훨씬 쉬워집니다.
이 게시물에서는 몇 가지 일반적인 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)
결론
이러한 리팩토링 기술을 사용하면 단일 책임 원칙을 준수하고 클래스와 메서드를 제어하는 데 도움이 됩니다.
이 기사가 재미있었다면 친구들과 공유하여 그들도 즐길 수 있도록 해주세요 🙂