Delegation ใน programming หมายถึงการมอบหมาย task จากส่วนหนึ่งของโปรแกรมไปอีกส่วนหนึ่ง มันเป็น essential technique ใน object-oriented programming เสริมสร้าง clean, maintainable code โดยการให้แน่ใจว่าแต่ละ object หรือ method รับผิดชอบ task หรือ behavior เฉพาะ
การเข้าใจและใช้ delegation เป็น key ในการ mastering Ruby และ object-oriented languages อื่นๆ Delegation ส่งเสริม separation of concerns ทำให้โค้ดของคุณ modular และเข้าใจง่าย ทดสอบง่าย และ refactor ง่าย
ในบทความนี้ เราจะดำดิ่งสู่สามวิธีในการ achieve delegation ใน Ruby: การใช้ explicit delegation, Forwardable module และ ActiveSupport::Delegate (สำหรับ Rails)
มาเริ่มกัน!
Delegation ใน Ruby
มาเริ่มด้วยการอภิปราย explicit delegation — การเรียกเมธอดภายในเมธอด จากนั้นเราจะสำรวจ built-in Forwardable module และว่ามันสามารถ streamline delegation ได้อย่างไร สุดท้ายเราจะครอบคลุม ActiveSupport::Delegate Rails-specific delegation tool ที่มี handy features
Explicit Delegation (การมอบหมายอย่างชัดเจน)
ในรูปแบบที่ง่ายที่สุด Delegation สามารถ achieve ได้โดยการ explicitly เรียกเมธอดภายในอีกเมธอดหนึ่ง Approach นี้มักถูกใช้เมื่อ delegated method 属于 separate object หรือเมื่อ delegation เรียบง่ายพอที่ไม่คุ้มค่าที่จะใช้ advanced techniques
การ implement explicit delegation ใน Ruby straightforward มาลอง example ของ Printer class ที่ใช้ HP object เพื่อ print text:
ในตัวอย่างข้างต้น print method ของ Printer class explicitly delegates formatting task ไปที่ HP class โดยการเรียก format method ของมัน Delegation นี้ outsources printing responsibility ไปอีกคลาสอย่างง่ายและอ่านง่าย
Explicit delegation common ใน real-world applications เพราะมันส่งเสริม separation of concerns และ maintainable code ตัวอย่างเช่น คุณอาจพบ technique นี้ใช้ใน applications ที่ต้องการ communication ระหว่าง different services ที่ one service เรียกอีก service เพื่อ perform specific task
เพิ่มเติม explicit delegation อาจ useful เมื่อ building adapters หรือ wrappers รอบ third-party libraries เพราะมันอนุญาตให้คุณ isolate interaction กับ external code
สรุป Explicit delegation เป็น straightforward และ effective way เพื่อ delegate tasks ระหว่าง objects ใน Ruby โดยการเรียกเมธอดภายในอีกเมธอด คุณสามารถ delegate responsibilities ได้ง่าย ทำให้โค้ด maintainable และส่งเสริม separation of concerns
Ruby's Forwardable Module
Forwardable module เป็น built-in Ruby library ที่ให้ streamlined และ flexible approach มากกว่าในการ delegate methods เทียบกับ explicit delegation โดย include Forwardable module ในคลาสของคุณ คุณได้ access to methods เช่น def_delegator และ def_delegators ทำให้ delegation เป็นเรื่องง่าย
เพื่อเริ่มต้นกับ Forwardable module ให้ include มันในคลาสและใช้ def_delegator และ def_delegators methods เพื่อ delegate one หรือ multiple methods ตามลำดับ มา revisit Printer example ด้วย Formatter class ใหม่และ implement Forwardable module:
ในตัวอย่างข้างต้น เราใช้ def_delegator เพื่อ delegate format method จาก Formatter class หากคุณต้องการ delegate multiple methods พร้อมกัน คุณสามารถใช้ def_delegators ตัวอย่างเช่น หาก Formatter class มี additional methods เช่น capitalize คุณสามารถ delegate พวกมันแบบนี้:
เมื่อใช้ Forwardable module มี potential drawbacks สำคัญบางอย่างที่ต้องพิจารณา:
- ขั้นแรก ให้แน่ใจว่า target object ถูก initialized ก่อนใช้ delegation มิฉะนั้นคุณอาจเจอ errors
- ที่สอง overuse ของ delegation อาจนำไปสู่ potential confusion ใน code readability เพราะอาจ unclear ว่ามีธอดไหนเป็นของคลาสและไหนเป็น delegated
- สุดท้าย อาจมี slight performance overhead เมื่อใช้ Forwardable เทียบกับ direct method calls อย่างไรก็ตาม overhead นี้ generally negligible ใน most applications
สำหรับข้อมูลลึกซึ้งเพิ่มเติมเกี่ยวกับ Forwardable module ดู Forwardable documentation
ActiveSupport::Delegate สำหรับ Rails Applications
ActiveSupport::Delegate เป็น delegation utility ที่ Rails 提供 ให้ concise syntax สำหรับ delegate methods ไป associated objects แม้จะมี similarities กับ built-in Forwardable module ของ Ruby ActiveSupport::Delegate เสนอ additional options และ features tailored สำหรับ Rails applications
เพื่อใช้ ActiveSupport::Delegate เพียงแค่เรียก delegate method ในคลาสและระบุ method(s) ที่จะ delegate พร้อม target object มา revisit Printer และ Formatter example และ implement delegation โดยใช้ ActiveSupport::Delegate:
ActiveSupport::Delegate เสนอ additional options และ features ที่ useful ใน various scenarios ตัวอย่างเช่น คุณสามารถใช้ :prefix option เพื่อ prepend prefix ไป delegated method หากคุณอยาก delegate multiple methods พร้อมกัน เพียง list พวกมันก่อน to: option:
สิ่งนี้ generate methods เช่น formatter_format, formatter_bold, และ formatter_italic ใน Printer class delegating ไป respective methods ใน Formatter class
ActiveSupport::Delegate มักใช้ใน real-world Rails projects เพื่อ delegate methods ระหว่าง associated models หรือ objects ตัวอย่างเช่น หากคุณมี User model ที่ belongs_to organization คุณสามารถ delegate name method จาก organization model ไป User model แบบนี้:
สิ่งนี้อนุญาตให้คุณ access organization's name ผ่าน user object: user.organization_name
สรุป ActiveSupport::Delegate เป็น powerful tool สำหรับ Rails applications ที่ enable concise และ expressive delegation of methods โดย leverage additional options และ features คุณสามารถสร้าง maintainable และ well-organized code ที่ปฏิบัติตาม principles ของ object-oriented programming ใน context ของ Rails projects
สำหรับข้อมูลลึกซึ้งเพิ่มเติมเกี่ยวกับ ActiveSupport::Delegate และ all available options ดู Rails ActiveSupport documentation
Comparison of Delegation Techniques (การเปรียบเทียบ Delegation Techniques)
Explicit delegation เป็น straightforward approach สูงสุดสำหรับ delegation ต้องการ manually defined methods ที่เรียก desired methods จาก delegated object แม้ technique นี้ simple และไม่ต้อง external libraries อาจ too verbose เมื่อ delegate growing number of methods
Forwardable module built-in ใน Ruby เสนอ streamlined way มากกว่าในการ delegate methods โดยใช้ def_delegator และ def_delegators methods คุณสามารถ delegate one หรือ multiple methods concisely
ActiveSupport::Delegate part ของ Rails' ActiveSupport library ให้ declarative way ในการ handle method delegation ด้วย clean syntax และ additional options เช่น prefixing มันเป็น expressive tool ใน Rails context เทียบกับ explicit delegation ActiveSupport::Delegate expressive และ less verbose มากกว่า โดยเฉพาะเมื่อ delegate multiple methods อย่างไรก็ตาม มันต้องการ Rails ดังนั้นไม่ suitable สำหรับ non-Rails Ruby projects
การเลือก delegation technique ขึ้นอยู่กับ specific needs และ application ของคุณ ในขณะที่ explicit delegation เสนอ simplicity และ clarity Forwardable module ให้ streamlined approach มากกว่า และ ActiveSupport::Delegate ให้ powerful, Rails-specific solution การเข้าใจ options เหล่านี้ ให้คุณเลือก technique ที่ fit กับโปรเจกต์และ coding style ของคุณดีที่สุด
สรุป
จาก explicit delegation ไป built-in Forwardable module หรือ Rails-specific ActiveSupport::Delegate แต่ละ technique เสนอ unique benefits และ potential drawbacks Technique ที่คุณควรเลือกขึ้นอยู่กับ specific context, nature ของโปรเจกต์ และ personal coding style ของคุณ
การเข้าใจ techniques เหล่านี้ไม่ได้แค่ขยาย Ruby programming skills ของคุณ แต่วัสดุคุณให้เขียน code ที่ modular, readable และ maintainable มากขึ้น ด้วยความรู้นี้ คุณพร้อมกว่าเดิมที่จะ tackle complex problems ด้วย eloquent design
Happy delegating!
P.S. หากคุณต้องการอ่านโพสต์ Ruby Magic ทันทีที่เผยแพร่ ให้สมัครสมาชิก newsletter Ruby Magic ของเรา และจะไม่พลาดโพสต์เด็ดๆ ไป!
Jeff Morhous
ผู้เขียนแขก Jeff Morhous เป็น Software Engineer เขียนโค้ดและแก้ bugs เพื่อช่วยผู้ป่วยได้รับยาที่พวกเขาต้องการ วันนี้เขา focused บนการทำ web applications ด้วย Ruby on Rails แตในอดีตเขาใช้ Swift, Java และ Kotlin สำหรับ iOS และ Android development
บทความทั้งหมดโดย Jeff Morhous