รูปแบบ ActiveRecord เป็นไปตาม / สนับสนุนหลักการออกแบบ SOLID หรือไม่?


43

ฉันสนใจว่ารูปแบบ ActiveRecord สร้างชื่อเสียงจาก Ruby on Rails กระตุ้นหรือกีดกันการใช้หลักการออกแบบSOLID

ตัวอย่างเช่นสำหรับฉันแล้ววัตถุ ActiveRecord นั้นมีทั้งตรรกะของโดเมนและตรรกะการคงอยู่ซึ่งเป็นการละเมิดความรับผิดชอบเดียว


6
Jim Weirich ในตอนท้ายของSOLID Ruby Talkของเขาในการประชุม Ruby 2009 ขอให้ผู้ชม: "วัตถุ ActiveRecord ใช้แนวคิดโดเมนและแนวคิดการติดตาสิ่งนี้ละเมิด SRP (หลักการความรับผิดชอบเดี่ยว) หรือไม่" ผู้ชมตกลงว่าจะละเมิด SRP จิมถามว่าสิ่งนี้รบกวนจิตใจพวกเขาหรือไม่ สมาชิกหลายคนของผู้ชมบอกว่าใช่ ทำไม? ทำให้การทดสอบหนักขึ้น มันทำให้วัตถุติดตาหนักกว่ามาก
David J.

คำตอบ:


56

มีการวิจารณ์ที่ถูกต้องบางอย่างใน ActiveRecord และเช่นเคยลุงบ๊อบ ผลรวมมันได้อย่างสมบูรณ์แบบ :

ปัญหาที่ฉันมีกับ Active Record คือมันสร้างความสับสนเกี่ยวกับรูปแบบการเขียนโปรแกรมทั้งสองที่แตกต่างกันมาก ตารางฐานข้อมูลเป็นโครงสร้างข้อมูล มันมีข้อมูลที่เปิดเผยและไม่มีพฤติกรรม แต่บันทึกการใช้งานดูเหมือนจะเป็นวัตถุ มันมีข้อมูลที่ "ซ่อน" และพฤติกรรมที่เปิดเผย ฉันใส่คำว่า "ซ่อน" ไว้ในเครื่องหมายคำพูดเพราะจริงๆแล้วข้อมูลไม่ได้ถูกซ่อนไว้ ActiveRecord Derivatives เกือบทั้งหมดส่งออกคอลัมน์ฐานข้อมูลผ่าน accessors และ mutators แท้จริงแล้ว Active Record นั้นมีความหมายที่จะใช้เหมือนโครงสร้างข้อมูล

ในทางกลับกันหลายคนวางวิธีการกฎธุรกิจไว้ในคลาส Active Record ซึ่งทำให้พวกเขาดูเหมือนจะเป็นวัตถุ สิ่งนี้นำไปสู่ภาวะที่กลืนไม่เข้าคายไม่ออก Active Record ตกลงด้านใดของบรรทัด มันเป็นวัตถุหรือไม่? หรือว่าเป็นโครงสร้างข้อมูล?

วิกิพีเดียสรุปการวิจารณ์ในส่วนความกังวลการตรวจสอบ :

ใน OOP แนวคิดของการห่อหุ้มมักจะขัดแย้งกับแนวคิดของการแยกข้อกังวล โดยทั่วไปแล้วรูปแบบที่สนับสนุนการแยกข้อกังวลมีความเหมาะสมมากกว่าสำหรับการทดสอบแบบแยกหน่วยในขณะที่รูปแบบที่สนับสนุนการห่อหุ้มนั้นง่ายต่อการใช้ API Active Record สนับสนุน encapsulation อย่างหนักจนถึงจุดที่การทดสอบที่ไม่มีฐานข้อมูลค่อนข้างยาก

สำหรับการใช้ Ruby on Rails โดยเฉพาะGavin King เขียน (เหมืองของเราที่เน้น):

ณ จุดนี้นักพัฒนาส่วนใหญ่ก็คิดว่าโอเคฉันจะรู้ได้อย่างไรว่า บริษัท มีคุณลักษณะอะไรโดยดูที่รหัสของฉัน และ IDE ของฉันจะเติมให้อัตโนมัติได้อย่างไร แน่นอนว่า Rails folks มีคำตอบอย่างรวดเร็วสำหรับคำถามนี้โอ้เพียงแค่ปิดไคลเอ็นต์ฐานข้อมูลของคุณและดูในฐานข้อมูล! จากนั้นสมมติว่าคุณทราบว่าการใช้ตัวพิมพ์ใหญ่และการทำพหูพจน์แบบอัตโนมัติของ ActiveRecord / อย่างสมบูรณ์แบบ / คุณจะสามารถเดาชื่อของแอตทริบิวต์ของคลาส บริษัท ของคุณและพิมพ์ด้วยตนเอง

ในการใช้ Ruby on Rails, John Januszczak เขียน (เหมืองที่เน้น):

ปัญหา # 1: วิธีคงที่

...

บางคนบอกว่าใช้วิธีการแบบคงที่จำนวนเพียงการเขียนโปรแกรมขั้นตอนและดังนั้นจึงเป็นการออกแบบ Object Oriented ที่ไม่ดี คนอื่นจะบอกว่าวิธีการคงที่คือการตายเพื่อทดสอบ

ปัญหา # 2: การตั้งค่าการกำหนดค่าทั่วโลก

...

ดังนั้นจึงไม่มีการฉีดพึ่งพาระดับบัญชีในตัวอย่างของฉันและโดยการขยายในกรณีบัญชี อย่างที่เราทุกคนควรรู้ตอนนี้การมองหาสิ่งต่าง ๆ นั้นแย่มาก ๆ !

แหล่งข้อมูลเพิ่มเติมอีกเล็กน้อยเกี่ยวกับสาเหตุที่ทำให้ ActiveRecord และ ORM โดยทั่วไปถือว่าเป็นรูปแบบการต่อต้าน:

ActiveRecord รู้สึกเหมือนรูปแบบการต่อต้านที่มีประโยชน์มากแต่ฉันเห็นด้วยว่ามันขัดกับ SRP และยิ่งไปกว่านั้นมันขัดกับหลักการผกผันของการพึ่งพา


การอัปเดตที่สำคัญสำหรับ Rails 5+: "และ IDE ของฉันจะเติมพวกเขาให้อัตโนมัติได้อย่างไรแน่นอน Rails folks มีคำตอบอย่างรวดเร็วสำหรับคำถามนี้โอ้เพียงแค่ติดตั้งไคลเอนต์ฐานข้อมูลของคุณและดูในฐานข้อมูล!" ไม่ถูกต้อง อีกต่อไป ด้วย API คุณลักษณะคุณสามารถกำหนดคอลัมน์ที่มีอยู่ทั้งหมดในรุ่น
Filip Bartuzi

6

(ฉันสมมติว่าคลาส ActiveRecord มีการใช้งานโดยไม่มีความเป็นไปได้สำหรับการฉีดพึ่งพา)

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

ดังนั้น ActiveRecord จึงค่อนข้างจะต่อต้าน SRP และทำให้เกิดอาการปวดหัวในการบำรุงรักษา ดูเหมือนว่าจะใช้พลังงานไปเขียนการทดสอบหน่วย

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.