Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> Ruby

เชี่ยวชาญ Polymorphism ใน Ruby on Rails: คู่มือปฏิบัติจริง

หากเคยใช้เวลาสร้าง Object-Oriented Program (OOP) คุณน่าจะเคยใช้ Polymorphism ในแอป หรืออย่างน้อยก็เคยได้ยินคำศัพท์นี้

มันเป็นคำที่คาดว่าจะเห็นในหนังสือวิทยาศาสตร์หรือ Computer Science คุณอาจเคย Research Polymorphism และ Implement ในแอปโดยไม่เข้าใจแนวคิดชัดเจน

บทความนี้จะให้ความเข้าใจลึกขึ้นเกี่ยว Polymorphism โดยเฉพาะใน Ruby on Rails เราจะเจาะลึก:

  • การใช้ Polymorphism ในโลกจริง
  • Polymorphism ในการเขียนโปรแกรมผ่าน OOP
  • วิธีนำไปใช้ใน Rails App เพื่อรักษา Code คุณภาพสูง

เริ่มกันเลย!

Polymorphism ในโลกจริง

มีหลายวิธี Define Polymorphism ในบริบทต่างๆ ความหมายที่มีประโยชน์ ไม่ว่าบริบทใด คือ 'ความสามารถของ Object ที่จะแสดงรูปแบบมากกว่าหนึ่งรูปแบบ' จริงๆ แล้วถ้าแยกคำ Poly คือ 'หลาย' และ Morph คือ 'รูปแบบ'

ในโลกจริง ตัวอย่างพื้นฐานคือ ผู้หญิงที่เป็นตำรวจ น้องสาว ลูกของใครคนหนึ่ง แม่ของใครคนหนึ่ง แต่ละ Role กำหนดพฤติกรรมและมีส่วนทำให้เธอเป็นเธอ

Polymorphism และ Genetics

นอกเหนือจาก Programming Polymorphism เป็นคำที่เกี่ยวข้องกับ Biology และ Genetics ในบริบทนี้ Polymorphism หมายถึง Genetic Variations ที่ทำให้เกิด Forms หรือ Types ที่แตกต่างกันหลายแบบภายใน Species เดียวกัน

คิดถึง Jaguar Jaguar อาจมี Gene Variations หลายแบบ ส่งผลต่อสีขน ส่วนใหญ่สีน้ำตาลกับวงกลมดำ แต่บางตัววงกลมอาจสว่างหรือมืดกว่าเนื่องจาก Gene ที่ Mutated และบางตัวอาจมีขนสีดำ

สีขนที่แตกต่างกันใน Species นกเดียวกันเป็นตัวอย่าง Polymorphism อีกอย่าง พิจารณา Gouldian Finch ที่มีความแตกต่างชัดเจนในสีระหว่าง Individual

Monomorphism vs. Polymorphism

หากเรานำ Monomorphism มาเปรียบเทียบ จะเข้าใจ Polymorphism ดีกว่า อยู่ใน Biology Monomorphism คือ 'Species ที่มีเพียงหนึ่งรูปแบบ' รักษารูปแบบนั้นตลอด Phase ของการพัฒนา

Penguin เป็น Monomorphic ยากมากที่จะแยกเพศ แม้สำหรับ Expert Gene Differences ใน Penguin น้อยมาก ทำให้ Physical Attributes เกือบ indistinguishable โดยเฉพาะขนาดและสีขาวดำ

Behavioral Cues มักเป็นวิธีง่ายสุดแยกเพศใน Species Monomorphic

มาหันมา Polymorphism ใน Programming โดยเฉพาะ

Polymorphism ใน OOP

พิจารณาความหมาย Polymorphism เราแรก — ความสามารถของ Object ที่จะแสดงรูปแบบมากกว่าหนึ่งรูปแบบ — เราสามารถเชื่อมโยงกับ OOP ได้ราบรื่น

ใน OOP เราสามารถใช้ Method เดียวกันผลลัพธ์ต่างกันได้โดยส่ง Object ต่างๆ เข้าไป เราอาจใช้ Conditionals ทำได้ แต่จะสร้าง Chunky Code และอาจเบี่ยงเบนจากหลัก DRY Polymorphism จำเป็นสำหรับ Clean และ Logical OOP Applications

มาดู 2 ตัวอย่าง Polymorphism Implement ใน Ruby OOP: ผ่าน Inheritance และ Duck-typing

Polymorphism และ Inheritance ใน Ruby

Inheritance คือ Child Class สืบทอด Properties จาก Parent Class

ตัวอย่าง Polymorphism ด้วย Inheritance:


โค้ดด้านบนมี Child Class 2 ตัว — Stringed และ Percussion — สืบทอดจาก Parent Class Instrument ตัวอย่างนี้ Polymorphic เพราะเราเรียก Method: instrument_example — และ Output หลายรูปแบบ: Saxophone, Guitar, และ Drums

ตัวอย่าง Polymorphism ผ่าน Inheritance นี้คือ Override Method แต่ช่วยให้เข้าใจ Polymorphism ใน OOP Language ชัดเจนขึ้น

Duck-Typing และ Polymorphism ใน Ruby

ตัวอย่าง Polymorphism ใน OOP ที่ปฏิบัติได้มากกว่าคือ Duck-typing ตามด้านล่าง


แม้ Method ของแต่ละ Class จะชื่อ brand เราไม่ Override Method (ต่างจาก Polymorphic Inheritance) แทนที่จะสืบทอดจาก Parent Class ที่นี่เรามี 4 Independent Classes แต่ละอันมี Method ของตัวเอง Duck-typing มีประโยชน์ เพราะเราแค่ Iterate ผ่าน Classes เพื่อได้ Output ของแต่ละ Method (แทนที่จะเรียก Method แยกกัน)

อีกครั้ง Duck-typing เป็น Polymorphic เพราะเราเรียก Method — brand — และ Generate Output ที่หลายรูปแบบ: Gibson, Pearl, Fender, และ Casio แน่นอน Duck-typing และ Polymorphism ไม่จำเป็นสำหรับผลลัพธ์นี้ แต่ Implement Clean และ Logical Code ได้ดี

Polymorphism ใน Ruby on Rails

Polymorphism ทำงานได้ดีใน Rails เป็น Active Record Association หาก Models ทำสิ่งเดียวกันในเบื้องต้น เราสามารถรวมเป็น Model เดียวเพื่อสร้าง Polymorphic Relationship

อยู่กับธีมเครื่องดนตรี พิจารณา App ที่ User สามารถ Post, Comment, และ Review เครื่องดนตรี ดู ERD ด้านล่าง:

เชี่ยวชาญ Polymorphism ใน Ruby on Rails: คู่มือปฏิบัติจริง

ในตัวอย่างนี้ ERD สำหรับ App ที่ User Post เครื่องดนตรีพร้อมรายละเอียด User ยัง Comment บน Instrument ที่ Post ไปได้

User อื่น Rate เครื่องดนตรี และ Rate Comment เพื่อวัดความมีประโยชน์/ความถูกต้อง Active Record Associations เหล่านี้ทำงานได้ดีและ serve Purpose ของ App

ถ้าอยากเพิ่ม Associations อื่น? ต้องเพิ่มและซ้ำ Associations

เช่นอยากเพิ่ม Model user_rating เพื่อ Rate ความน่าเชื่อถือของ User ต้องสร้าง Table แยกกับ Associations ของตัวเอง หมายถึงเพิ่ม Relationship ใหม่ระหว่าง user และ user_rating ERD จะกลายเป็น:

เชี่ยวชาญ Polymorphism ใน Ruby on Rails: คู่มือปฏิบัติจริง

ตอนนี้เรามี 3 Models ที่ทำสิ่งเดียวกันคือ Rate Object แต่ใน Context ต่างกัน Associations เหล่านี้ พร้อมสำหรับ Polymorphic Association

มาดู ERD ที่ Rating Models เป็น Polymorphic:

เชี่ยวชาญ Polymorphism ใน Ruby on Rails: คู่มือปฏิบัติจริง

เนื่องจากมี Column rating ผมตั้งชื่อ Model ว่า reviews แทน ratings เพื่อหลีกเลี่ยงความสับสน ที่นี่ Non-review Models ยังมี Associations กับ Models อื่น แต่ Rating Models แยกต่างหากถูกรวมเป็น Review Model เดียว

reviewable_type และ reviewable_id ทำหน้าที่เดียวกับ Rating Models แยก โดย Represent ว่า Model ไหน Review เกี่ยวข้อง

Column reviewable_type เก็บ Class Name ของ Model (user, instrument_post, หรือ comment) และ reviewable_id เก็บ ID ที่ตรงกับ Model นั้น

เราสามารถใช้ 2 Columns นี้ Link Rating Integer กับ User, Post, หรือ Comment เฉพาะผ่าน Active Record Queries และ/หรือ Conditional Statements Foreign Key user_id ยังคงอยู่ใน Review Model เพราะช่วย Track ว่า User ไหนทิ้ง Review

ตอนนี้ Term '-able' ใน Polymorphic Model อาจดูแปลก แต่ Purpose จะชัดเจนตอนเราทำ Rails Magic

Review Model ถือว่า Polymorphic เพราะเรามี Model/Object เดียวที่ Represent และรับหลายรูปแบบ: User, Comment, และ Instrument Post Reviews

Implementing Polymorphism ใน Ruby on Rails

เวลา Implement Polymorphism ใน Rails App! สมมติเราสร้าง Model user, instrument_post, และ comment แล้ว เริ่ม Incorporate Polymorphic Model: reviews

แรก สร้าง Table และ Generate Model จาก Terminal:


นี่สร้าง Migration File:


File schema.rb อัปเดตหลังรัน Migration Option Polymorphic แปลง Column reviewable เป็น reviewable_type และ reviewable_id:



จำได้ไหม Term '-able' ด้านบน? มันคือ Rails Naming Convention สำหรับ Polymorphic Association ให้เราทำให้ User, Instrument Post, และ Comment 'reviewable' ได้

เพื่อ Rails Magic นี้ทำงาน ต้อง Ensure Models อื่น Associate ถูกต้องกับ Polymorphic Model




Model user, instrument_post, และ comment ตอนนี้สามารถ Reviewed และ Given Ratings ได้

หากเรามีอย่างน้อย 2 Users, 1 Comment, และ 1 Instrument Post แล้ว เราสามารถ Create และ Access Reviews ผ่าน Active Record Queries แบบต่างๆ:





มีอีกหลายวิธี Interact กับ Model reviews ขึ้นกับ Data ที่ต้อง Render สำคัญต้อง Share ว่า Parent Models สร้าง Review ยังไง ตราบใด Review Associate กับ User และ Reviewable Model Active Record จะ Link reviewable_id และ reviewable_type กับ Associated Model อัตโนมัติ

โดยไม่มี Polymorphism ใน Rails Examples จะมี Table มากกว่า Column ซ้ำ belongs_to และ has_many Associations ใน Models Polymorphism ลดความต้อง Join Tables ทำให้ Active Record Queries และ Associations ง่ายและเร็วขึ้น

สรุป: ใช้ Polymorphism สำหรับ Ruby Code ที่ Clean และ Logical

ในบทความนี้ เราสำรวจ Polymorphism ใน 2 สภาพแวดล้อมที่ต่างกัน: Biology และ Ruby Programming ในทั้งคู่ Polymorphism คือความสามารถของ Object ที่จะแสดงรูปแบบมากกว่าหนึ่งรูปแบบ

เราดูวิธี Implement Polymorphism ใน Ruby ผ่าน Inheritance และ Duck-typing ก่อนเจาะลึกการใช้ Polymorphism ใน Ruby on Rails โดยเฉพาะ

Polymorphism ช่วยเขียน Code ที่ Clean และ Logical เป้าหมายคือช่วยเพิ่ม OOP Concept สำคัญนี้ใน Toolbelt สำหรับ App ปัจจุบัน อนาคต และอาจรวมถึง App เก่าๆ

Happy Coding!

P.S. หากต้องการอ่านบทความ Ruby Magic ทันทีที่เผยแพร่ สมัคร Newsletter Ruby Magic ของเราและจะไม่พลาดบทความเด็ดๆ ไป!