ชี้แจง MVVM


15

เรากำลังจะเขียนแอปพลิเคชั่น WPF แรกของเราและเริ่มคุ้นเคยกับรูปแบบ MVVM เราได้สร้างแอปพลิเคชั่น Winform จำนวนมากและมีสถาปัตยกรรมที่ประสบความสำเร็จมากสำหรับเรา เรามีปัญหาเล็กน้อยในการแปลสถาปัตยกรรมนั้นหรือกำหนดว่าสถาปัตยกรรมบางอย่างของเราเหมาะสมกับรูปแบบ MVVM หรือไม่

ในอดีตเรามี Gui (exe หลัก) ที่สื่อสารกับ dll BusinessLogic BusinessLogic สื่อสารกับ DAL dll ผ่านเว็บเซอร์วิสและ DAL โต้ตอบกับ DB DAL, BusinessLogic และ GUI ล้วนอ้างถึง BusinessObjects dll เดียวกัน

เป็นสถาปัตยกรรม

การเปลี่ยนแปลงไปสู่ ​​MVVM นั้นค่อนข้างตรงไปตรงมา Gui ของเราจะยังคงมีมุมมอง BusinessOjbects ของเราจะยังคงมีรูปแบบและ DAL ของเราจะยังคงมีปฏิสัมพันธ์กับฐานข้อมูล (แม้ว่าเทคโนโลยีในการใช้พวกเขาอาจเปลี่ยนแปลง)

สิ่งที่เราไม่แน่ใจคือองค์ประกอบ BusinessLogic ของเรา ในอดีตนี้จะให้ฟังก์ชั่นสำหรับ GUI เพื่อเรียกไปแล้วเติมการควบคุมในมุมมอง (เช่น. GetCustomerList ซึ่งจะส่งกลับรายการของวัตถุลูกค้าหรือฟังก์ชั่น CRUD ทั่วไป)

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

องค์ประกอบ BusinessLogic ของเราเป็นตัวแทนของ ViewModels หรือไม่


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

คำตอบ:


19

โดยทั่วไปแล้วฉันจะไม่วางตรรกะทางธุรกิจไว้ในเลเยอร์โมเดลมุมมอง แต่คำว่า "ตรรกะทางธุรกิจ" นั้นทำให้เข้าใจผิด

Eric Evans ใช้แบบจำลองที่ตรรกะทางธุรกิจแบ่งออกเป็นสองประเภท

  • ตรรกะของโดเมน - ตรรกะที่เกี่ยวข้องกับโดเมนปัญหาจริงที่คุณกำลังแก้ไข
  • Application logic - ตรรกะที่เกี่ยวข้องกับความจริงที่ว่าคุณกำลังสร้างแอปพลิเคชัน

เขากล่าวถึงตัวอย่างของแอปพลิเคชันการบัญชี กฎเกี่ยวกับบัญชีโพสต์บัญชีภาษี ฯลฯ เป็นกฎของโดเมนกฎที่เกี่ยวข้องกับโดเมนของบัญชี ตรรกะเกี่ยวกับการนำเข้า / ส่งออก CSV ไม่มีส่วนเกี่ยวข้องกับโดเมนของการบัญชี กฎเหล่านี้มีอยู่จริงเพราะเรากำลังสร้างแอปพลิเคชันซอฟต์แวร์ นี่เป็นตัวอย่างของตรรกะแอปพลิเคชัน

กฎโดเมนไม่ควรเข้าไปในเลเยอร์โมเดลมุมมอง หากคุณกำลังติดตามรูปแบบ MVVM กฎของโดเมนจะเป็นไปโดยไม่มีคำถามในเลเยอร์โมเดล

กฎของแอปพลิเคชันเช่นการนำเข้า / ส่งออก CSV สามารถอยู่ในเลเยอร์มุมมองโมเดล แต่โดยส่วนตัวแล้วฉันต้องการแยกออกเป็นเลเยอร์ตรรกะของแอปพลิเคชันแยกต่างหาก

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

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


1
คำตอบที่ยอดเยี่ยม ฉันชอบจุดที่ทำให้แน่ใจว่า ViewModel มีตรรกะการนำเสนอเท่านั้น คุณสามารถเพิ่มลิงค์ที่เกี่ยวข้องกับคะแนน Eric Evans ของคุณได้หรือไม่?
user7676

ฉันสงสัยว่าฉันสามารถหาลิงก์ได้เพราะฉันเชื่อว่าฉันได้รับมาจากหนังสือของเขาที่ชื่อว่า Domain-Driven Design อย่างไรก็ตามฉันคิดว่ามันเป็นตัวอย่างที่ยอดเยี่ยมของความแตกต่างระหว่างโดเมนและแอปพลิเคชันตรรกะ เพิ่มเติมเกี่ยวกับหนังสือที่นี่books.google.dk/books/about/…
Pete

5

ใช่.

เลเยอร์ตรรกะทางธุรกิจนั้นแสดงโดยเลเยอร์ VM ดังนั้นเพียงแค่โยกย้ายแบบจำลองทางจิตของคุณ

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

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

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

ในกรณีที่สอง (เหตุการณ์การคลิกปุ่ม) เหตุการณ์การเปลี่ยนแปลง (คลิก) สามารถเชื่อมต่อกับการเรียกใช้ฟังก์ชันที่เปิดเผยโดย VM

ไม่ว่าจะด้วยวิธีใดก็มักจะเป็นเหตุการณ์ที่ลำดับลงใน VM ซึ่งจะเรียกโมเดลซึ่งจะเรียก DAL / DB

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


ขอบคุณสำหรับการยืนยัน เราเข้าใจถึงความแตกต่างของวิธีการที่ View โต้ตอบกับ ViewModel และจะรักษารูปแบบการเชื่อมโยงและวาง "การเรียก"
user7676

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

1
ฉันยอมรับว่าเลเยอร์ตรรกะทางธุรกิจนั้นแสดงโดยเลเยอร์ VM แต่ฉันคิดว่าบางส่วนของคำตอบของคุณอาจสับสน Viewชั้นมีขึ้นเพื่อเป็นการแสดงออกของ ViewModel หรือรุ่นดังนั้นแทนที่จะบอกว่าเหตุการณ์คลิกเป็นสายไปยังการเรียกฟังก์ชั่นใน VM ความหมายที่ดีกว่าจะบอกว่าคำสั่งใน VM ได้รับการแสดงเป็นปุ่ม ชั้นดู นอกจากนี้ฉันมักไม่ชอบเลเยอร์โมเดลของฉันที่สามารถเข้าถึง DAL ได้โดยตรงดังนั้นโดยทั่วไปโฟลว์แอปพลิเคชันของฉันจะไปVM -> DAL -> DBที่ซึ่งVMและDALทั้งสองใช้Modelวัตถุข้อมูลธรรมดา
Rachel

4
ฉันไม่เห็นด้วยกับคำตอบนี้ ViewModel เป็นรูปแบบของมุมมองมันมีตรรกะดูไม่ใช่ตรรกะทางธุรกิจ ViewModels เป็นส่วนหนึ่งของเลเยอร์การนำเสนอ
simoraman

1
@simoraman - รูปแบบ MVPVMนั้นสอดคล้องกับสิ่งที่คุณกำลังแนะนำ ฉันคิดว่า MVPVM เป็นรูปแบบที่ดี แต่ค่อนข้างหนักสำหรับแอปขนาดเล็ก ฉันอยากจะแนะนำให้คุณใส่ความคิดของคุณลงในคำตอบและช่วยตอบคำถามนี้

5

คุณถูกต้องแล้วว่าคุณจะต้องแทนที่ BusinessLogic dll ของคุณด้วยเลเยอร์ ViewModel ของคุณ แต่ฉันคิดว่าความแตกต่างที่ยิ่งใหญ่ที่สุดที่คุณจะเผชิญคือการที่เลเยอร์ View / UI โต้ตอบกับเลเยอร์ ViewModel / BusinessLogic ของคุณ

ใน WinForms GUI เป็นแอปพลิเคชั่นของคุณและรับผิดชอบการทำงานของแอพพลิเคชั่น ใน WPF / MVVM ViewModels ของคุณคือแอปพลิเคชั่นของคุณและ GUI กลายเป็นเพียงส่วนติดต่อผู้ใช้ที่ใช้งานง่ายเพื่อโต้ตอบกับ ViewModels

ตัวอย่างเช่นด้วย WinForms คุณอาจมี DataGrid และปุ่มและเมื่อคุณคลิกปุ่มที่คุณโทรBusinessLogicLayer.GetProducts()และโหลดวัตถุผลิตภัณฑ์ที่เป็นผลลัพธ์ลงใน DataGrid

ด้วย WPF คุณจะมี ViewModel ที่มีObservableCollection<Products>และICommand GetProductsและดำเนินการคำสั่งเรียก DAL และโหลดคอลเลกชันของผลิตภัณฑ์ แต่เพื่อให้อินเทอร์เฟซที่ใช้งานง่ายสำหรับสิ่งนี้คุณจะต้องสร้างมุมมองที่แสดงผล ViewModel ของคุณโดยใช้ DataGrid สำหรับคอลเลกชันผลิตภัณฑ์และปุ่มสำหรับคำสั่ง GetProducts

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


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