การปรับโครงสร้างใหม่

เมื่อเรามีฟังก์ชั่นการทำงานแล้ว เราก็สามารถย้อนกลับไปและคิดว่าจะจัดโครงสร้างโค้ดของเราอย่างไรให้ดีที่สุด เป้าหมายคือการทำให้ปลั๊กอินของเรามีความชัดเจน เข้าใจได้ และบำรุงรักษาได้มากที่สุดเท่าที่จะเป็นไปได้ กระบวนการปรับปรุงและปรับปรุงโครงสร้างของโค้ดที่มีอยู่โดยไม่เปลี่ยนพฤติกรรมนี้เรียกว่าการปรับโครงสร้างใหม่

นี่คือฟังก์ชันเริ่มต้นอีกครั้ง:

(define (scheme-hello-world)
  ;; Set the message handler to output the message to a GUI dialog box
  (lumi-message-set-handler 0)
  (lumi-message "Hello world!\n")

  ;; Set the message handler to output the message to the Error Console
  (lumi-message-set-handler 2)
  (lumi-message "Hello world!\n")

  ;; Send the message to the terminal, the OS window that launched Lumi
  (display "Hello world!\n"))

ชื่อฟังก์ชันคือชื่อของฟังก์ชัน และพารามิเตอร์คือสิ่งที่ฟังก์ชันยอมรับเป็นอินพุต เนื้อความคือบล็อกของโค้ดที่ทำงานเมื่อมีการเรียกใช้ฟังก์ชัน

แบบฟอร์มบทคัดย่อ:

(define (function-name parameter)
  body)

การทำซ้ำโค้ด

ลบการทำซ้ำในช่วงต้น (lumi-message "Hello world!\n") ถูกทำซ้ำสองครั้ง และสตริงข้อความถูกทำซ้ำสามครั้ง ตัวแปรแก้สตริงที่ซ้ำกัน

ตัวแปร

ใน Scheme ตัวแปรจะมี “ขอบเขต” ซึ่งเป็นที่ทราบ และขอบเขตนั้นถูกตั้งค่าโดยใช้คำสั่ง let ตัวแปรถูกผูกไว้กับค่าในส่วนการโยง และตัวแปรมีขอบเขตอยู่ในเนื้อหาที่อนุญาต ตัวแปรเป็นที่รู้จักเฉพาะภายในบล็อกการอนุญาตและไม่สามารถเข้าถึงได้ภายนอก

(let ((variable value))
  body)

แนะนำตัวแปรที่เรียกว่า “ข้อความ”:

(define (scheme-hello-world)
  (let ((message "Hello world!\n"))

    ;; Set the message handler to output the message to a GUI dialog box
    (lumi-message-set-handler 0)
    (lumi-message message)

    ;; Set the message handler to output the message to the Error Console
    (lumi-message-set-handler 2)
    (lumi-message message)

    ;; Send the message to the terminal, the OS window that launched Lumi
    (display message)))

ในตัวอย่างของเรา เราได้ใช้ตัวแปรชื่อ “ข้อความ” ที่เชื่อมโยงกับสตริง “Hello world!\n” ซึ่งช่วยให้เราสามารถเปลี่ยนแปลงเนื้อหาข้อความได้เพียงครั้งเดียวแทนที่จะเป็นสามครั้ง ซึ่งช่วยลดโอกาสที่จะเกิดข้อผิดพลาดและทำให้โค้ดมีความยืดหยุ่นมากขึ้น

การแยกฟังก์ชั่น

ในการเขียนโปรแกรมเชิงฟังก์ชัน การปรับโครงสร้างโค้ดเพื่อแยกตรรกะที่ใช้ซ้ำได้ออกเป็นฟังก์ชันที่แยกจากกันถือเป็นแนวทางปฏิบัติทั่วไป เมื่อทำเช่นนี้ ฟังก์ชันหลัก จะง่ายขึ้นมากและมุ่งเน้นไปที่เป้าหมายระดับสูงมากขึ้น ในขณะที่ ฟังก์ชันที่แยกออกมา จะดูซับซ้อนมากขึ้นเนื่องจากจะจัดการกับตรรกะโดยละเอียด นี่เป็นความตั้งใจและสอดคล้องกับหลักการสำคัญของการเขียนโปรแกรมเชิงฟังก์ชัน เช่น ความเป็นโมดูล การแยกข้อกังวล และความสามารถในการอ่าน นี่คือการปรับโครงสร้างใหม่ สวัสดีชาวโลก! หลังจากการสกัด

แยกตรรกะ:

# !/usr/bin/env lumi-scheme-interpreter-0.1

;; Main Function
(define (scheme-hello-world)
  (let ((message "Hello world!\n"))

    (send-message message 'gui)
    (send-message message 'error-console)
    (send-message message 'terminal)))

;; Function to handle message output to various destinations
(define (send-message message output)
  (cond
    ;; Send to the Error Console
    ((eq? output 'error-console)
       ;; Set the handler to Error Console
       (lumi-message-set-handler 2)
       (lumi-message message))

    ;; Send to the GUI dialog box
    ((eq? output 'gui)
       ;; Set the handler to GUI dialog
       (lumi-message-set-handler 0)
       (lumi-message message))

    ;; Send to the terminal window
    ((eq? output 'terminal)
       ;; Terminal output is handled with display
       (display message)))

  ;; Restore the default message handler to the Error Console
  (lumi-message-set-handler 2))

(scheme-register-procedure "scheme-hello-world"
  "Hello world!"
  "A Scheme procedure plug-in"
  "Mark Sweeney"
  "Under GNU GENERAL PUBLIC LICENSE Version 3"
  "2024")

(scheme-menu-register
  "scheme-hello-world"
  "<Image>/Funky")

สัญลักษณ์

ในตัวอย่างข้างต้น มีการใช้ชนิดข้อมูลที่เรียกว่าสัญลักษณ์ เช่น ‘gui’ สัญลักษณ์จะถูกส่งผ่านเป็นพารามิเตอร์ไปยังฟังก์ชันส่งข้อความ และสามารถใช้เพื่อตัดสินใจตามเงื่อนไขง่ายๆ เช่นเดียวกับคีย์สัญลักษณ์ พวกมันเป็นตัวระบุที่ไม่ซ้ำกัน สำหรับข้อมูลเพิ่มเติมเกี่ยวกับสัญลักษณ์ โปรดไปที่ หน้านี้

ลดความซับซ้อนของฟังก์ชันหลัก

ในฟังก์ชันดั้งเดิม (scheme-hello-world) ตรรกะทั้งหมดสำหรับการส่งข้อความไปยังเอาต์พุตต่างๆ (GUI, Error Console, Terminal) ได้ถูกผสมเข้ากับฟังก์ชันหลัก หลังจากการปรับโครงสร้างใหม่ ฟังก์ชันหลักจะเน้นไปที่ สิ่งที่ต้องทำ เพื่อส่งข้อความไปยังปลายทางต่างๆ

ฟังก์ชันหลักที่ปรับโครงสร้างใหม่นั้นง่ายกว่า:

  • ระบุวัตถุประสงค์อย่างชัดเจน: ส่งข้อความเดียวกันไปยังเอาต์พุตหลายรายการ
  • หลีกเลี่ยงไม่ให้ตรรกะหลักยุ่งเหยิงด้วยโค้ดที่ซ้ำกัน เช่น การตั้งค่าตัวจัดการข้อความสำหรับเอาต์พุตที่แตกต่างกัน
  • อ่านและทำความเข้าใจได้ง่ายขึ้นในทันที

ความซับซ้อนของฟังก์ชันที่แยกออกมา

ในทางตรงกันข้าม ฟังก์ชัน (ส่งข้อความ) คือตำแหน่งที่มีตรรกะโดยละเอียดอยู่ ตอนนี้จัดการรูปแบบการทำงานที่แตกต่างกันสำหรับแต่ละเอาต์พุต (GUI, Error Console, Terminal) ฟังก์ชันนี้ซับซ้อนกว่าเดิมเล็กน้อย แต่ตอนนี้ รวมศูนย์ และ แยก แล้ว

เกี่ยวข้องกับสิ่งนี้กับการเขียนโปรแกรมเชิงฟังก์ชัน

ในการเขียนโปรแกรมเชิงฟังก์ชัน ฟังก์ชันต่างๆ จะถูกมองว่าเป็น พลเมืองชั้นหนึ่ง ซึ่งหมายความว่าสามารถนำกลับมาใช้ใหม่ ส่งต่อ และรวมเข้าด้วยกันเพื่อสร้างพฤติกรรมที่ซับซ้อนมากขึ้น เป้าหมายคือ:- แยกย่อยปัญหา ออกเป็นชิ้นเล็กๆ อิสระ

  • แยกความซับซ้อน ออกเป็นฟังก์ชันเล็กๆ ที่จัดการงานเฉพาะ เช่น send-message
  • ทำให้ฟังก์ชันระดับสูงกว่าเรียบง่าย เพื่อให้สามารถมุ่งเน้นไปที่การประสานโฟลว์ของข้อมูลและการดำเนินการ โดยไม่จำเป็นต้องทราบรายละเอียดว่าแต่ละงานบรรลุผลสำเร็จอย่างไร
  • การแยกข้อกังวล: ฟังก์ชันจะดูแลวิธีการส่งข้อความตามประเภทเอาต์พุต ซึ่งแยกตรรกะนี้ออกจากฟังก์ชันหลัก
  • ความเป็นโมดูล: ด้วยการจัดการตรรกะการส่งข้อความทั้งหมดในที่เดียว เราจึงสามารถทำการเปลี่ยนแปลงได้อย่างง่ายดาย (เช่น การเพิ่มตัวเลือกเอาต์พุตใหม่) โดยไม่ต้องเปลี่ยนแปลงฟังก์ชันหลัก
  • การนำกลับมาใช้ใหม่ได้: ฟังก์ชัน send-message สามารถนำมาใช้ซ้ำได้ ซึ่งหมายความว่าหากเราต้องการส่งข้อความไปยังเอาต์พุตหลายรายการในโค้ดของเรา เราก็สามารถเรียกใช้ฟังก์ชันนี้แทนการเขียนตรรกะที่คล้ายกันใหม่ได้

ด้วยการปรับโครงสร้างใหม่ ฟังก์ชันหลักในตัวอย่างนี้จะกลายเป็นคำสั่ง ประกาศ ของสิ่งที่เกิดขึ้น (“ส่งข้อความไปยังสถานที่สามแห่ง”) ในขณะที่ความซับซ้อนของวิธีการส่งข้อความเหล่านั้นถูกแยกออกไปในฟังก์ชัน send-message