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