คำแนะนำโครงสร้างโครงการแอปพลิเคชันแบบชั้น MVVM, DDD และ WPF


17

ฉันกำลังพยายามตั้งค่าโครงสร้างแอปพลิเคชันของฉันใน VS และฉันต้องการ "ลอง" และพิสูจน์ในอนาคตให้อยู่ในระดับที่เหมาะสม แอปพลิเคชั่นนี้จะเป็น WPF เขียนใหม่ของแอป Winform เก่าที่ไม่ได้ทำตามอนุสัญญา ไม่มีเลเยอร์เทียร์คำย่อ ฯลฯ ...

มันเป็นแอพพลิเคชั่นสำหรับองค์กรขนาดใหญ่พอสมควร ฉันวางแผนที่จะใช้ Linq To SQL เป็นฐานข้อมูลของฉันและมักจะเป็น MS SQL นอกจากนี้ฉันมีชุดทักษะที่มีอยู่กับมัน

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

เมื่อฉันติดตาม MVVM โครงสร้างโฟลเดอร์ของฉันอาจมีลักษณะเช่นนี้:

Views
Models
ViewModels
Helpers

แต่วิธีที่เหมาะกับ DDD แบบเลเยอร์เรียบง่ายที่โครงสร้างโครงการของฉันอาจมีลักษณะเช่นนี้:

MyApp.UI
MyApp.Domain
MyApp.Data

ฉันจะใส่Modelsใน Domain layer หรือฉันมี 3 รุ่นว่าPerson? สิ่งนี้นำไปสู่คำถามอื่นที่ฉันจะวางที่เก็บและการแมปของวัตถุ DB กับวัตถุโดเมนหรือไม่ ฉันจะถือว่าข้อมูล ...

Viewsฉันจะได้รับใน UI แต่จะViewModelsยัง

ในที่สุดฉันจะฝังตรรกะทางธุรกิจของฉันไว้ที่ไหน

ฉันพบสิ่งต่อไปนี้ใน CodePlex, DDD ตัวอย่างและมันมีความช่วยเหลือบางอย่าง แต่ดูเหมือนว่าจะเป็นสำหรับเว็บแอปแม้ว่ามันอาจไม่สำคัญและความไม่รู้ของฉันก็ส่องผ่าน

อย่าเข้าใจฉันผิดฉันรู้ว่าฉันสามารถมีโฟลเดอร์ได้มากและเรียกมันตามที่ฉันต้องการ ฉันพยายามหาที่ที่จะวางสิ่งต่าง ๆ เพื่อที่จะได้ขนาดไม่ได้เรียกว่าสถานที่เหล่านั้น

หัวใจของคำถามของฉันอาจปรากฏเช่นนี้
ฉันได้วัตถุที่สร้างขึ้นโดยtblPerson *.dbmlสิ่งนี้ชัดเจนและจะอยู่ในเลเยอร์ "ข้อมูล" ของฉัน
ตอนนี้ฉันจะมีรุ่น DTO โดเมนรุ่นหรือสิ่งที่เรียกว่าในแยก Layer (โครงการ?) Personเรียกว่า ฉันจะต้องมีMapperสำหรับPersonการtblPersonที่ผมไม่แน่ใจว่าการที่จะนำ
แล้วฉันจะมี ViewModel สำหรับการพูดEditPersonที่จะมีมันเป็นคุณสมบัติของตัวเองที่จะดึงจากPersonแต่อาจเป็นไปได้มากขึ้นเช่นกัน
ในที่สุดฉันก็มีมุมมองที่ถูกผูกไว้กับ ViewModel นั้น ....

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


Linq To SQL ไม่เหมาะสำหรับโครงการขนาดใหญ่ ใช้ Entity Framework หรือ ORM อื่นเช่น nHibernate นอกจากนี้แอปพลิเคชันเฉพาะลูกค้านี้หรือไคลเอ็นต์เซิร์ฟเวอร์หรือไม่
ร่าเริง

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

คำตอบ:


5

MVVM เป็นรูปแบบ UI และใช้ในไคลเอนต์

ส่วนต่าง ๆ ของโดเมนใน DDD ที่ใช้ในไคลเอนต์อาจเป็น (ส่วนหนึ่งของ) โมเดล

View และ ViewModel เป็นไคลเอนต์เท่านั้น

ฉันวางที่เก็บไว้ใน (หรือใกล้) โมเดลเพราะพวกเขาซิงโครไนซ์โมเดลกับแบ็คเอนด์

ใช่หลายครั้งสิ่งนี้จะส่งผลให้หลายคลาสบุคคลในเนมสเปซที่แตกต่างกัน พวกเขาอาจเริ่มคล้ายกันมาก แต่อาจแตกต่างกันมากหลังจากทำซ้ำหรือเผยแพร่สองสามครั้ง

แก้ไข

เพื่อชี้แจงส่วนเกี่ยวกับที่เก็บข้อมูลและเพื่ออธิบายเพิ่มเติมเกี่ยวกับการวางตำแหน่งของตรรกะทางธุรกิจ

หากคุณกำลังสร้างระบบที่มีไคลเอ็นต์แยกต่างหากและที่เก็บฝั่งเซิร์ฟเวอร์ / แบ็คเอนด์สามารถใช้ในไคลเอนต์และเซิร์ฟเวอร์ ในไคลเอนต์เพื่อให้เป็นนามธรรมของเซิร์ฟเวอร์และในเซิร์ฟเวอร์เพื่อให้เป็นนามธรรมของเซิร์ฟเวอร์อื่น ๆ และแหล่งข้อมูล มันเป็นเพียงรูปแบบ

สำหรับกฎธุรกิจ: หากคุณใช้กฎเหล่านี้ในไคลเอนต์ต้องแน่ใจว่าคุณบังคับใช้ในเซิร์ฟเวอร์ด้วย อย่าไว้วางใจลูกค้า กฎทางธุรกิจในไคลเอนต์อนุญาตให้ตรวจสอบอินพุตอย่างรวดเร็วและป้องกันการไปกลับไปยังเซิร์ฟเวอร์

ฉันคิดว่า DDD อยู่ในฝั่งเซิร์ฟเวอร์และ 'รั่วไหล' ไปยังไคลเอนต์


2

คุณมีทิศทางที่ถูกต้องในการเลือกรูปแบบการออกแบบ MVVM สำหรับแอปพลิเคชัน WPF

Do I put the Models in the Domain layer?

ใช่โมเดลของคุณสามารถอยู่ในโดเมนได้

Where would I put my Repository and mappings of DB Object to Domain Object?

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

ViewModels also?

ViewModels ของคุณควรอยู่ที่ฝั่งไคลเอ็นต์ (เลเยอร์) คุณสามารถสร้างรูปแบบการรับชมของคุณจาก DTO หนึ่งรายการขึ้นไปขึ้นอยู่กับมุมมองของคุณ

เกี่ยวกับDDDฉันขอแนะนำให้อ่านเกี่ยวกับเรื่องนี้และชี้แจงให้คุณทราบจริงๆว่าต้องมีรูปแบบการออกแบบที่ขับเคลื่อนด้วยโดเมน นี่คือการสนทนาที่95% ของการใช้งานซอฟต์แวร์ทั้งหมดตกอยู่ในหมวดหมู่ "ไม่ดีสำหรับการใช้ DDD"

แก้ไข:มีการเพิ่มการอ้างอิงข้างต้นและขอขอบคุณสำหรับ @Den!


กรุณาแสดงความคิดเห็นเมื่อลงคะแนน
Yusubov

1
DDD fanboys ต้องการใช้ทุกที่ ลิงค์ที่เกี่ยวข้อง: stackoverflow.com/questions/810606/is-ddd-a-waste-of-time
Den

@Den ขอบคุณสำหรับลิงค์! ฉันวางแผนที่จะมองหามัน
Yusubov

1

ก่อนที่เราจะเจาะลึกลงไปว่าเกิดอะไรขึ้นเรามาพูดถึงสิ่งที่แต่ละชั้นควรทำ

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

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

ฉันจะทำโครงงานของฉันดังนี้:

 project.Views
 project.ViewModel
 project.Model
 project.DataStructs

และสามารถเพิ่มเลเยอร์นี้ได้ตามต้องการ:

 project.Helpers

ฉันกำลังแยก Helpers ออกจากสแต็คที่เหลือดังนั้นมันจึงไม่สับสนว่าเป็นเลเยอร์ของสแต็กแอปพลิเคชันของคุณ

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

โดเมนของคุณจะเป็นปัญหาที่คุณกำลังพิจารณา
รูปแบบโดเมนจะสอดคล้องกับ ViewModels ที่คุณสร้างเป็นหลัก เล็กน้อยในมุมมอง; และชิ้นเล็ก ๆ ภายใน Model / DataStructs

ดังนั้นวิธีการที่จะทำงานออกมา?
หากคุณมีความสามารถในการเปลี่ยนแปลงโครงสร้างข้อมูลที่มีอยู่แล้วสิ่งใหม่ที่คุณสร้างขึ้นควรสัมพันธ์กับปัญหาที่คุณพยายามแก้ไข มีวัตถุของลูกค้าหรือไม่ จากนั้นคุณควรมี / a บางตารางที่เกี่ยวข้องกับลูกค้า มีใบแจ้งหนี้หรือผลิตภัณฑ์? เรื่องเดียวกัน - ควรสร้างตารางและโครงสร้างที่จับคู่กับวัตถุทางธุรกิจเหล่านั้น

โดเมนจะแสดงผ่านวัตถุ ViewModel ของคุณและมุมมองที่คุณนำเสนอของวัตถุเหล่านั้น หากคุณต้องการแก้ไขบันทึกของลูกค้าคุณจะมี VM สำหรับจัดการงานนั้น

ตามคำถามของคุณ:

  1. อย่าพยายามวาง DDD ลงบน MVVM มันจะไม่ทำงาน DDD ไม่ใช่รูปแบบเค้าโครง แต่เป็นวิธีการดูปัญหาโดยรวมของคุณ
  2. พื้นที่เก็บข้อมูลและการแมปจะใช้งานได้ทั้งในโครงการ data หรือ project.Model ตามความเหมาะสม
  3. ไม่มีเลเยอร์ที่เรียกว่า UI เว้นแต่ว่าเป็นสิ่งที่คุณต้องการเรียกใช้โปรเจ็กต์มุมมอง
  4. ตรรกะทางธุรกิจจะอยู่ใน View-Model

1
ตกลงมีบางคนอาจไม่รู้ติดตามคำถาม (1) คุณจะทำให้แต่ละโครงการแยกต่างหากหรือเพียงแค่โฟลเดอร์ (เช่น Project.View ฯลฯ .. )? (2) DataStructs เป็นตำแหน่งที่คุณจะใส่ * .dbml หรือ Project.Data (3) ในความคิดของคุณฉันจะไม่มี Project.Domain? ฉันเคยเห็นว่าใช้ไม่กี่ครั้งคือเหตุผลที่ฉันถาม
Paladin หักเห

@RractractPaladin - 1) เพียงโฟลเดอร์ภายในโครงการ คุณสามารถโต้แย้งว่า Data ควรเป็นโครงการของตัวเอง จากมุมมองการบำรุงรักษาวิธีใดเทียบเท่า 2) ใช่แน่นอน 3) ไม่ฉันไม่มีโฟลเดอร์. Domain IMO หน้าที่ของเราคือแมปแอปพลิเคชันกับโดเมนปัญหาธุรกิจ ดังนั้นโดเมนจะแทรกซึมทุกชั้นของโครงการ
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.