ในระบบ MVC รหัสการคงอยู่ของฐานข้อมูลควรอยู่ที่ไหน


21

ฉันเห็นการกำหนดค่าหลายอย่างสำหรับการเก็บข้อมูลในฐานข้อมูล โดยทั่วไปแล้วการออกแบบสามประเภทนั้นดูเหมือนกันในมุมโลกของฉัน:

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

ฉันสงสัยว่าการกำหนดค่าใด (ถ้ามี) เป็นแนวคิดที่ง่ายที่สุดในการใช้ / เข้ากันได้กับสถาปัตยกรรม MVC มากที่สุด?

(หากไม่ใช่รายการที่ฉันแสดงโปรดให้รายละเอียดคร่าวๆ / ภาพรวมซึ่งเป็นส่วนหนึ่งของคำตอบ)

คำตอบ:


13

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

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


2
ฉันไม่เห็นด้วยในระดับหนึ่ง การใช้ประโยชน์จากความคงทนเป็นรูปธรรมคือแอปพลิเคชันตรรกะและดังนั้นจึงเป็นของชั้นแอพลิเคชันและไม่ได้อยู่ในโดเมนชั้น เลเยอร์โดเมน (ที่มีโมเดลโดเมน) ควรไม่สนใจการคงอยู่ของโปรแกรมธุรกิจแบบไม่เป็นทางการ ตัวควบคุมเป็นผู้ประพันธ์ สามารถประสาน (data-) บริการ, UI และรูปแบบโดเมน
Falcon

1
@ เหยี่ยว: ในขณะที่ตัวควบคุมควรควบคุมเมื่อมีการโหลดข้อมูลและยืนยันไปยังฐานข้อมูล แต่ก็ไม่เป็นไรที่จะบอกให้แบบจำลองทำเช่นนั้น การใช้ ORM (มาตรฐานหรือม้วนของคุณเอง) มักจะหมายถึงการบอกให้แบบจำลองเพื่อโหลด / บันทึกซึ่งจากนั้นมอบหมายให้ ORM อีกวิธีหนึ่งคือให้คอนโทรลเลอร์บอก ORM ให้โหลด / บันทึกบางสิ่งผ่านคลาสโมเดลที่จะโหลด (พร้อมเกณฑ์การเลือก) หรืออินสแตนซ์โมเดลเพื่อบันทึก ไม่ว่าจะด้วยวิธีใดการโหลด / การบันทึกจริงจะเชื่อมโยงกับโมเดล
Marjan Venema

@Marjan Venema: ใช่ฉันเห็นด้วย แต่คำถามคือรหัสที่ควรมีชีวิตอยู่ ฉันมุ่งมั่นที่จะรักษารูปแบบของการเพิกเฉยต่อความพยายามให้มากที่สุดเท่าที่จะทำได้และเป็นเพียงรูปแบบของโดเมนที่มีพฤติกรรมและการโต้ตอบ สิ่งอื่นจะอยู่ในเลเยอร์แอปพลิเคชัน (เนื่องจากเป็นแอปพลิเคชันของโมเดลของฉัน) การแมปข้อมูล / การเข้าถึงข้อมูลนั้นแยกออกจากตัวแบบโดเมนอย่างสมบูรณ์และยังสามารถดูแลการกำหนดเวอร์ชัน (อัปเกรด / ดาวน์เกรด) แอปพลิเคชันของการเข้าถึงข้อมูลยังมีชีวิตอยู่ในเลเยอร์แอปพลิเคชัน (ซึ่งมีบริการที่เก็บ ฯลฯ )
Falcon

@ ฟอลคอน: ใช่นั่นเป็นวิธีที่ดีในการทำและเป็นวิธีที่ฉันเคยทำในอดีตโดยใช้คลาสการทำแผนที่แยกต่างหาก อย่างไรก็ตามด้วยการมาถึงของ RTTI (Delphi) และการไตร่ตรอง (.Net และอื่น ๆ ) ทำให้ฉันไม่มีความมั่นใจเกี่ยวกับการใช้สิ่งเหล่านี้ร่วมกับคำอธิบายประกอบของแอตทริบิวต์ของ Business Object Model เพื่อให้ทุกอย่างเป็นไปได้และใช้เพียงโอเวอร์โหลด / หรือคลาสเริ่มต้นการเขียนโค้ดโดยเฉพาะเพื่อดูแลการกำหนดเวอร์ชันฐานข้อมูล
Marjan Venema

5

ในความเป็นจริงแล้ว MVC นั้นเป็นรูปแบบการใช้งาน UI เป็นส่วนใหญ่ดังนั้นคำถามจึงค่อนข้างสงสัย อย่างไรก็ตามมีตัวเลือกภาพใหญ่เพียงสองตัวเลือกเท่านั้น โดยทั่วไปแล้วคอนโทรลเลอร์ของคุณจะส่งคำขอให้โหลดหรือบันทึกเอนทิตีในแบบจำลองของคุณโดยใช้ 1) ชั้นบริการบางประเภทหรือ 2) รูปแบบ Active Record

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

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

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


3

ในระบบ MVC (model-view-controller) โมเดลจะมีข้อมูล ดังนั้นฉันเชื่อว่าการคงอยู่ของฐานข้อมูลควรอยู่ในนั้น


2

ตัวอย่าง MVC ระดับสูงส่วนใหญ่ที่ฉันเคยเห็นมีinfrastructureเลเยอร์แยกต่างหากซึ่งมีรหัสการนำไปใช้จริงของฐานข้อมูล (เช่นการเรียกเฉพาะไปยัง NHibernate หรือ EF หรือ Linq หรือเลเยอร์ข้อมูลของคุณ) ในขณะที่เลเยอร์ "แบบจำลอง" (เช่นกัน เลเยอร์ "โดเมน") มีส่วนต่อประสานที่กำหนดบริการข้อมูล


0

การปฏิบัติมาตรฐานใน MVC คือการรวมโครงสร้างข้อมูลและการคงอยู่ในชั้น M (odel)

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

ตัวอย่างจะเป็นที่เก็บที่คุณมีอินสแตนซ์ของคลาสข้อมูลมากมายเช่น:

Clients repository

AllClients()
RecentClients()
ClientByID(int id)

คุณจะสามารถจัดระเบียบแบบจำลองโดเมนของคุณได้ดีขึ้นและยังสามารถเข้าถึงข้อมูลของคุณได้หลายวิธี แต่ยังคงชั้นข้อมูล / แบบจำลองจะกะทัดรัดและแข็งแกร่ง

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