นางแบบอ้วนและตัวควบคุมผอมฟังดูเหมือนสร้างโมเดลของพระเจ้า


94

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

  1. คอนโทรลเลอร์และเราเตอร์ไม่ได้ทำงานที่แตกต่างกันมากนักนอกเหนือจากการเรียกใช้เมธอดบนโมเดลที่เหมือนพระเจ้าตามเส้นทาง
  2. นางแบบทำมากเกินไป การส่งอีเมลการสร้างความสัมพันธ์การลบและการปรับเปลี่ยนโมเดลอื่น ๆ การจัดคิวงาน ฯลฯ โดยพื้นฐานแล้วตอนนี้คุณมีวัตถุคล้ายพระเจ้าที่ควรทำทุกอย่างที่อาจเกี่ยวข้องกับการสร้างแบบจำลองและการจัดการกับข้อมูลหรือไม่ก็ได้

คุณลากเส้นตรงไหน? นี่ไม่ได้ตกอยู่ในรูปแบบพระเจ้าหรือ?

คำตอบ:


142

อาจไม่ใช่ความคิดที่ดีที่สุดที่จะมองว่า Rails เป็นส่วนประกอบหลักของรูปแบบการออกแบบ MVC กรอบดังกล่าวถูกสร้างขึ้นโดยมีข้อบกพร่องโดยธรรมชาติบางอย่าง (ฉันอธิบายไว้อย่างละเอียดในโพสต์อื่น ) และตอนนี้ชุมชนเพิ่งเริ่มจัดการกับผลเสีย คุณสามารถดูการพัฒนา DataMapper2 เป็นขั้นตอนสำคัญขั้นแรก

ทฤษฎีบางอย่าง

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

แนวคิดหลักที่อยู่เบื้องหลังรูปแบบ MVC คือการแยกข้อกังวลและขั้นตอนแรกคือการแบ่งระหว่างเลเยอร์การนำเสนอและเลเยอร์โมเดล เช่นเดียวกับที่เลเยอร์การนำเสนอแบ่งออกเป็นตัวควบคุม (อินสแตนซ์ที่รับผิดชอบในการจัดการกับอินพุตของผู้ใช้) มุมมอง (อินสแตนซ์รับผิดชอบตรรกะ UI) และเทมเพลต / เลย์เอาต์เลเยอร์โมเดลก็เช่นกัน

ส่วนสำคัญที่เลเยอร์โมเดลประกอบด้วย:

  • วัตถุโดเมน

    หรือที่เรียกว่าโดเมนเอนทิตีอ็อบเจ็กต์ทางธุรกิจหรือโมเดลอ็อบเจ็กต์ (ฉันไม่ชอบชื่อหลังนั้นเพราะมันเพิ่มความสับสน) โครงสร้างเหล่านี้เป็นสิ่งที่คนมักเรียกกันผิด ๆ ว่า "โมเดล" พวกเขามีหน้าที่รับผิดชอบในการบรรจุกฎทางธุรกิจ (คณิตศาสตร์และการตรวจสอบความถูกต้องสำหรับหน่วยเฉพาะของลอจิกโดเมน)

  • Abstractions การจัดเก็บ:

    โดยปกติจะดำเนินการโดยใช้รูปแบบตัวทำแผนที่ข้อมูล (อย่าสับสนกับORMซึ่งใช้ชื่อนี้ในทางที่ผิด) โดยปกติอินสแตนซ์เหล่านี้จะได้รับมอบหมายให้มีการจัดเก็บข้อมูลจากและการดึงข้อมูลไปยังอ็อบเจ็กต์โดเมน ออบเจ็กต์โดเมนแต่ละตัวสามารถมีตัวทำแผนที่ได้หลายแบบเช่นเดียวกับที่เก็บข้อมูลหลายรูปแบบ (DB, แคช, เซสชัน, คุกกี้, / dev / null)

  • บริการ:

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

นอกจากนี้ยังมีโครงสร้างที่อาจจะอยู่ในช่องว่างระหว่างกลุ่มเหล่านี้: DAOs , หน่วยงานและที่เก็บ

อ้อ ... และเมื่อเราพูด (ในบริบทของเว็บ) เกี่ยวกับผู้ใช้ที่โต้ตอบกับแอปพลิเคชัน MVC ไม่ใช่มนุษย์ แท้จริงแล้ว "ผู้ใช้" คือเว็บเบราว์เซอร์ของคุณ

แล้วเทพล่ะ?

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

การเปลี่ยนแปลงดังกล่าวอาจทำให้เกิดปฏิกิริยาบางอย่างในทันทีหรือส่งผลต่อข้อมูลที่อินสแตนซ์ดูร้องขอจากเลเยอร์โมเดลหรือทั้งสองอย่าง

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

ปิดบันทึก

ด้วยวิธีนี้คุณจะได้แอปพลิเคชันที่สามารถทดสอบหน่วยได้ทุกระดับมี coupling ต่ำ (หากใช้งานอย่างถูกต้อง) และมีสถาปัตยกรรมที่เข้าใจได้ชัดเจน

อย่างไรก็ตามโปรดทราบว่า MVC ไม่ได้มีไว้สำหรับแอปพลิเคชันขนาดเล็ก หากคุณกำลังเขียนหน้าสมุดเยี่ยมโดยใช้รูปแบบ MVC คุณกำลังทำผิด รูปแบบนี้มีไว้สำหรับการบังคับใช้กฎหมายและคำสั่งในการใช้งานขนาดใหญ่

สำหรับผู้ที่ใช้ PHP เป็นภาษาหลัก โพสต์นี้อาจเกี่ยวข้อง เป็นคำอธิบายที่ยาวขึ้นเล็กน้อยเกี่ยวกับเลเยอร์โมเดลพร้อมตัวอย่างโค้ดเล็กน้อย


มีประโยชน์มากและตอบโจทย์! คุณรู้จักหนังสือเล่มใดที่อธิบายเพิ่มเติมเกี่ยวกับรูปแบบสถาปัตยกรรม MVC หรือไม่? โดยเฉพาะอย่างยิ่งในส่วนของโมเดลที่ทุกคนเข้าใจผิดคิดว่า "โมเดลเป็นตัวแทนของข้อมูลและไม่ได้ทำอะไรอื่นเลย" และฟังดูเหมือนแนวคิดของวัตถุโดเมนไม่ใช่ 'Model' -> tomdalling.com/blog/software-design/…
thermz

1
@thermz, afaikไม่มีหนังสือที่เกี่ยวข้องกับรูปแบบ MVC โดยเฉพาะ ฉันมักจะบอกให้คนอื่นอ่านPoEAAแล้วไปขุดคุ้ย บางทีรายการลิงก์นี้อาจมีประโยชน์ ฉันพบว่าเมื่อผู้คนเข้าใจหลักการและแนวคิดของ OOP อย่างมั่นคงรูปแบบจะค่อนข้างเข้าใจง่าย
tereško

@ tereškoคำตอบที่สวยงาม Hibernate บรรลุเป้าหมายนี้หรือไม่? ฉันไม่มั่นใจในคำตอบที่นี่ -> stackoverflow.com/questions/1308096/…
Ankan-Zerob

@ Ankan-Zerob อย่างที่คุณสังเกตเห็นฉันไม่ใช่นักพัฒนา java แต่จากสิ่งที่ฉันรู้เกี่ยวกับ Hibernate มันมีชุดเครื่องมือที่สมบูรณ์สำหรับเลเยอร์การคงอยู่ มันจะทำให้คุณเป็นส่วนหนึ่งของสิ่งที่อธิบายไว้ในนั้น แต่ไม่ใช่เลเยอร์โมเดลที่สมบูรณ์
tereško

3
@johnny ไม่เท่าที่ฉันรู้ สิ่งที่เรียกว่า "เฟรมเวิร์ก mvc" ของ php ส่วนใหญ่เป็นรูปแบบของ Rails และเป็นส่วนหนึ่งของหลักสูตรนี้ส่วนใหญ่มาพร้อมกับโซลูชัน ORM ตามบันทึกที่ใช้งานอยู่ (สิ่งเหล่านี้มีความเปราะบางต่อการเปลี่ยนแปลง DB) คุณสามารถนำสิ่งนี้ไปใช้กับ SF2.x หรือ ZF2.x ได้ แต่ประเด็นของกรอบงานไม่ใช่การใช้งาน / บังคับใช้สถาปัตยกรรมเฉพาะ แต่เพื่อจัดหาเครื่องมือ นอกจากนี้เมื่อพูดถึง MVC จะมีการใช้งานโดยใช้รหัสแอปพลิเคชันไม่ใช่กรอบ
tereško

5

หากมีการนำคลาส "model" ไปใช้ไม่ดีแสดงว่าคุณกังวล คลาสโมเดลไม่ควรทำอีเมล (งานโครงสร้างพื้นฐาน)

คำถามที่แท้จริงคือโมเดลใน MVC บ่งบอกถึงอะไร ไม่ จำกัด เฉพาะคลาส POCO ด้วยวิธีการบางอย่าง แบบจำลองใน MVC หมายถึงข้อมูลและตรรกะทางธุรกิจ ถือว่าเป็นส่วนเหนือของโมเดล POCO หลักคลาสสิก

View ==== Controller ==== Model ---> Business Process Layer -> Core Models

โยนชุดโครงสร้างพื้นฐานและเลเยอร์การเข้าถึงข้อมูลและใช้การแทรกเข้าไปใน BPL จากนั้นกระบวนการของคุณจะใช้ MVC ตามที่ตั้งใจไว้

BPL อาจเรียกใช้รูปแบบ UoW / Respository และดำเนินการตามกฎทางธุรกิจและเรียกใช้คุณสมบัติโครงสร้างพื้นฐานโดยใช้ Objects หรือส่วนต่อประสาน

ดังนั้นคำแนะนำในการทำให้คอนโทรลเลอร์ผอมไม่ได้หมายความว่าคลาส "บุคคล" ในโมเดล Core แบบคลาสสิกควรมี 50 วิธีและโทรหาอีเมลโดยตรง คุณคิดถูกแล้วที่คิดว่าผิด

คอนโทรลเลอร์อาจยังคงต้องใช้ในการสร้างอินสแตนซ์และฉีดคลาสโครงสร้างพื้นฐานลงใน BPL หรือเลเยอร์หลักหากเรียกโดยตรง ควรมีเลเยอร์ธุรกิจหรืออย่างน้อยคลาสที่จัดการการเรียกข้ามคลาสโมเดลคลาสคลาสสิกอ็อบเจ็กต์ นั่นคือ "มุมมอง" ของฉันอยู่ดี ;-)

สำหรับการใช้ MVC ทั่วไปคำอธิบายวิกิhttp://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller

บล็อกเล็ก ๆ ที่พูดถึง "M" ใน MVC http://www.thedeveloperday.com/skinny-controllers/


1
ถ้าคุณไม่เห็นด้วยอย่างน้อยก็สุภาพพอที่จะแสดงความคิดเห็นของคุณ
phil soady

-1

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

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