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 ด้วย 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)

บทสรุป

การใช้เทคนิคการรีแฟคเตอร์เหล่านี้จะช่วยให้คุณปฏิบัติตามหลักการความรับผิดชอบเดียวและควบคุมคลาสและเมธอดของคุณ

หากคุณชอบบทความนี้โปรดแบ่งปันกับเพื่อน ๆ ของคุณเพื่อให้พวกเขาได้สนุกกับมันเช่นกัน 🙂