หากคุณไม่คุ้นเคยกับคำศัพท์นั้น การปรับโครงสร้างใหม่คือการปรับปรุงคุณภาพของโค้ดโดยไม่เปลี่ยนแปลงสิ่งที่ทำ วิธีนี้จะทำให้โค้ดของคุณทำงานได้ง่ายขึ้นมาก
ในบทความนี้ คุณจะได้เรียนรู้เทคนิคการปรับโครงสร้าง 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 ด้วย Method Object
บางครั้งคุณมีวิธีการที่ยิ่งใหญ่ที่ไม่สามารถควบคุมได้ ในกรณีนี้ การปรับโครงสร้างใหม่อาจทำได้ยาก เนื่องจากวิธีการขนาดใหญ่มักจะมีตัวแปรในเครื่องจำนวนมาก ทางออกหนึ่งคือการใช้การปรับโครงสร้าง '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)
บทสรุป
การใช้เทคนิคการรีแฟคเตอร์เหล่านี้จะช่วยให้คุณปฏิบัติตามหลักการความรับผิดชอบเดียวและควบคุมคลาสและเมธอดของคุณ
หากคุณชอบบทความนี้โปรดแบ่งปันกับเพื่อน ๆ ของคุณเพื่อให้พวกเขาได้สนุกกับมันเช่นกัน 🙂