Silverlight - ดูโมเดล
ในบทนี้เราจะมาดูเทคนิคที่สำคัญในการพัฒนาซอฟต์แวร์ของ Silverlight การใช้ไฟล์ View Models.
view model เป็นส่วนสำคัญซึ่งแนะนำเทคนิคที่เรียกว่าการนำเสนอแบบแยกส่วนโดยการแยกมุมมองออกจากโมเดล
View Models นำเสนอวิธีเดียวในการบรรลุการนำเสนอแบบแยกส่วนและเราจะดูว่าพวกเขาใช้ประโยชน์จากการผูกข้อมูลของ Silverlight อย่างไรเพื่อลดจำนวนรหัสที่จำเป็นในอินเทอร์เฟซผู้ใช้ของคุณ
ความท้าทายในการพัฒนา UI
View Modelsได้รับการออกแบบมาเพื่อแก้ปัญหาบางอย่างที่เกิดขึ้นบ่อยครั้งเมื่อพัฒนาซอฟต์แวร์ส่วนต่อประสานผู้ใช้ บางทีสิ่งที่สำคัญที่สุดก็คือโค้ดส่วนต่อประสานผู้ใช้มักจะยากที่จะทดสอบอย่างแยกไม่ออกโดยเฉพาะอย่างยิ่งกับการทดสอบหน่วยอัตโนมัติ นอกจากนี้ยังมีปัญหาด้านคุณภาพของโค้ดที่อาจส่งผลต่อความยืดหยุ่นและความสามารถในการบำรุงรักษาโค้ดของคุณอย่างต่อเนื่อง
หากคุณทำตามเส้นทางของการต่อต้านน้อยที่สุดที่เครื่องมือออกแบบของ Visual Studio นำคุณไปสู่คุณอาจต้องใส่โค้ดมากเกินไปในโค้ดที่อยู่เบื้องหลัง
เป็นเรื่องปกติมากที่จะเห็นฟังก์ชันการทำงานของแอปพลิเคชันจำนวนมากถูกเพิ่มเข้าไปในโค้ดด้านหลัง
นักพัฒนาเพียงไม่กี่คนที่วางแผนจะใส่ตรรกะทางธุรกิจลงในคลาสอินเทอร์เฟซผู้ใช้ แต่เนื่องจาก Visual Studio ทำให้ตัวจัดการเหตุการณ์ของคุณกลายเป็นสถานที่ที่สะดวกเกินไปในการทำสิ่งต่างๆให้เสร็จสิ้น
เป็นที่ยอมรับอย่างกว้างขวางว่าซอฟต์แวร์สามารถพัฒนาและบำรุงรักษาได้ง่ายกว่าหากชั้นเรียนมีการกำหนดไว้อย่างดีและมีความรับผิดชอบที่แคบพอสมควร
รหัสเบื้องหลังงานคือการโต้ตอบโดยตรงกับวัตถุที่ประกอบเป็นส่วนต่อประสานผู้ใช้ในกรณีที่จำเป็น
ทันทีที่คุณเริ่มวางโค้ดที่ทำให้ตัดสินใจได้ว่าแอปพลิเคชันของคุณทำงานอย่างไรซึ่งมีแนวโน้มที่จะนำไปสู่ปัญหา
ไม่เพียง แต่ตรรกะของแอปพลิเคชันจะไหลไปสู่โค้ดที่ควรจะเกี่ยวข้องกับอินเทอร์เฟซผู้ใช้เท่านั้นนักพัฒนาบางรายเริ่มพึ่งพาการควบคุมและอ็อบเจ็กต์อินเทอร์เฟซผู้ใช้อื่น ๆ เพื่อรักษาสถานะแอปพลิเคชันที่สำคัญ
โมเดลจะเก็บข้อมูลไว้เท่านั้นมุมมองจะเก็บวันที่ที่จัดรูปแบบไว้และตัวควบคุม (ViewModel) ทำหน้าที่เป็นผู้ประสานงานระหว่างทั้งสอง คอนโทรลเลอร์อาจรับอินพุตจากมุมมองและวางไว้บนโมเดลและในทางกลับกัน
การนำเสนอแบบแยกส่วน
เพื่อหลีกเลี่ยงปัญหาที่เกิดจากการใส่ตรรกะของแอปพลิเคชันไว้ในโค้ดด้านหลังหรือ XAML ควรใช้เทคนิคที่เรียกว่า separated presentation. การมี XAML และโค้ดอยู่ข้างหลังโดยมีขั้นต่ำที่จำเป็นสำหรับการทำงานกับออบเจ็กต์ส่วนติดต่อผู้ใช้โดยตรงคลาสอินเทอร์เฟซผู้ใช้ยังมีโค้ดสำหรับพฤติกรรมการโต้ตอบที่ซับซ้อนตรรกะของแอปพลิเคชันและอื่น ๆ ตามที่แสดงด้านล่างทางด้านซ้าย
คุณสมบัติที่สำคัญของการนำเสนอแบบแยกส่วน -
ด้วยการนำเสนอที่แยกจากกันคลาสอินเทอร์เฟซผู้ใช้จะง่ายกว่ามาก แน่นอนว่ามี XAML แต่โค้ดที่อยู่เบื้องหลังนั้นใช้งานได้จริง
ตรรกะของแอปพลิเคชันอยู่ในคลาสแยกต่างหากซึ่งมักเรียกกันว่า model.
นักพัฒนาจำนวนมากพยายามใช้การผูกข้อมูลเพื่อเชื่อมต่อองค์ประกอบใน XAML โดยตรงกับคุณสมบัติในโมเดล
ปัญหาคือ model เกี่ยวข้องกับสิ่งที่แอปพลิเคชันทำและไม่เกี่ยวข้องกับวิธีที่ผู้ใช้โต้ตอบกับแอปพลิเคชัน
อินเทอร์เฟซผู้ใช้ส่วนใหญ่มีสถานะบางอย่างที่ไม่ได้อยู่ในโมเดลแอ็พพลิเคชัน ตัวอย่างเช่นหากอินเทอร์เฟซผู้ใช้ของคุณใช้การลากและวางบางสิ่งบางอย่างต้องติดตามสิ่งต่างๆเช่นตอนนี้รายการที่ลากอยู่ในขณะนี้ลักษณะที่ปรากฏควรเปลี่ยนไปอย่างไรเมื่อเคลื่อนผ่านเป้าหมายการวางที่เป็นไปได้และเป้าหมายการวางเหล่านั้นอาจเป็นอย่างไร เปลี่ยนเมื่อรายการถูกลากไป
สถานะประเภทนี้อาจมีความซับซ้อนอย่างน่าประหลาดใจและจำเป็นต้องได้รับการทดสอบอย่างละเอียด
ในทางปฏิบัติโดยปกติคุณต้องการให้คลาสอื่นนั่งอยู่ระหว่างอินเทอร์เฟซผู้ใช้และโมเดล สิ่งนี้มีสองบทบาทที่สำคัญ
ขั้นแรกจะปรับรูปแบบแอปพลิเคชันของคุณสำหรับมุมมองอินเทอร์เฟซผู้ใช้เฉพาะ
ประการที่สองเป็นที่ที่ตรรกะการโต้ตอบที่ไม่สำคัญใด ๆ อาศัยอยู่และด้วยเหตุนี้ฉันหมายถึงรหัสที่จำเป็นเพื่อให้อินเทอร์เฟซผู้ใช้ของคุณทำงานในแบบที่คุณต้องการ
รุ่น / View / ViewModel
View Modelเป็นตัวอย่างของวิธีการนำเสนอที่แยกออกจากกัน แต่ขอให้เรามีความชัดเจนว่าเรามีสิ่งใดบ้างในแต่ละเลเยอร์ มีสามชั้น -
- Model
- View
- ViewModel
รุ่น
มันคือ classic โมเดลอ็อบเจ็กต์ที่ประกอบด้วยคลาส C # ธรรมดาที่ไม่มีความสัมพันธ์โดยตรงกับอินเทอร์เฟซผู้ใช้
โดยทั่วไปคุณคาดหวังว่ารหัสโมเดลของคุณจะสามารถคอมไพล์ได้โดยไม่ต้องอ้างอิงไลบรารีส่วนติดต่อผู้ใช้ใด ๆ ในความเป็นจริงคุณอาจจะสามารถใช้ซอร์สโค้ดเดียวกันและรวบรวมลงในแอปพลิเคชัน Silverlight แอปพลิเคชันคอนโซล. NET ธรรมดาหรือแม้แต่รหัสเว็บฝั่งเซิร์ฟเวอร์
ประเภทในแบบจำลองควรแสดงถึงแนวคิดที่แอปพลิเคชันของคุณใช้งานได้
ดู
โดยปกติ View เป็น UserControl อาจเป็น MainPage ของคุณหรืออาจเป็นเพียงบางส่วนของเพจของคุณ
ในแอปพลิเคชัน Silverlight ส่วนใหญ่คุณควรแบ่งส่วนติดต่อผู้ใช้ของคุณออกเป็นส่วนเล็ก ๆ เพื่อกำหนด UserControl หรือ View สำหรับแต่ละส่วน
แอพพลิเคชั่น Silverlight ไม่ซ้ำใครในแง่นี้ สิ่งที่ชัดเจนเฉพาะของ Silverlight คือ View ยิ่งอินเทอร์เฟซผู้ใช้ของคุณมีความละเอียดมากเท่าไหร่สิ่งที่ดีกว่าก็มักจะเป็นเช่นนั้น ไม่เพียง แต่คุณมีโอกาสน้อยที่จะเดินทางข้ามผู้พัฒนารายอื่นที่ทำงานกับไฟล์เดียวกัน แต่การทำให้สิ่งเล็ก ๆ และเรียบง่ายเป็นธรรมชาติไม่สนับสนุนทางลัดที่นำไปสู่โค้ดคล้ายสปาเก็ตตี้
ตัวอย่างเช่นเป็นเรื่องปกติมากที่จะกำหนดไฟล์ View เพื่อแสดงรายการแต่ละรายการในรายการ
ViewModel
สุดท้ายสำหรับแต่ละ Viewคุณเขียนไฟล์ ViewModel. ดังนั้นนี่คือหนึ่งในคุณสมบัติที่สำคัญของไฟล์ViewModel ชั้นเรียน
มีไว้เพื่อแสดงมุมมองเฉพาะ ViewModel มีความเชี่ยวชาญในการนำเสนอสิ่งต่างๆเช่นรายการข้อมูลเฉพาะที่ปรากฏในรายการ
นี่คือเหตุผลที่เรียกว่าไฟล์ ViewModel; จะปรับโมเดลต้นแบบโดยเฉพาะสำหรับมุมมองเฉพาะ เช่นเดียวกับรุ่นViewModelยังเป็นคลาส C # ธรรมดา ไม่จำเป็นต้องได้มาจากประเภทใดประเภทหนึ่ง
ในขณะที่เกิดขึ้นนักพัฒนาบางคนพบว่าสะดวกในการใส่ฟังก์ชันทั่วไปบางอย่างลงในคลาส ViewModel พื้นฐาน แต่รูปแบบไม่ต้องการสิ่งนั้น โดยเฉพาะอย่างยิ่งViewModelไม่ได้มาจากประเภทเฉพาะของ Silverlight ใด ๆ อย่างไรก็ตามแตกต่างจากโมเดลตรงที่สามารถใช้ประเภท Silverlight ในคุณสมบัติได้
ตัวอย่างเช่น ViewModel ของคุณอาจเลือกที่จะทำให้บางส่วนของอินเทอร์เฟซผู้ใช้ของคุณสามารถมองเห็นได้ภายใต้เงื่อนไขบางประการเท่านั้นดังนั้นคุณอาจระบุคุณสมบัติของประเภท System.Windows.Visibility ซึ่งเป็นประเภทที่องค์ประกอบ Silverlight ใช้สำหรับคุณสมบัติการมองเห็น ทำให้สามารถเชื่อมโยงการมองเห็นขององค์ประกอบเช่นพาเนลเข้ากับ ViewModel ได้โดยตรง
ตัวอย่าง
ให้เราดูตัวอย่างง่ายๆที่เราจะใช้ Model-View-ViewModel (MVVM) แนวทาง
Step 1 - สร้างโครงการ Silverlight Application ใหม่ SilverlightMVVMDemo.
Step 2 - เพิ่มสามโฟลเดอร์ (Model, ViewModel และ Views) ลงในโปรเจ็กต์ของคุณดังที่แสดงด้านล่าง
Step 3 - เพิ่มคลาส StudentModel ในโฟลเดอร์ Model และวางโค้ดด้านล่างในคลาสนั้น
using System.ComponentModel;
namespace SilverlightMVVMDemo.Model {
public class StudentModel {}
public class Student : INotifyPropertyChanged {
private string firstName;
private string lastName;
public string FirstName {
get { return firstName; }
set {
if (firstName != value) {
firstName = value;
RaisePropertyChanged("FirstName");
RaisePropertyChanged("FullName");
}
}
}
public string LastName {
get { return lastName; }
set {
if (lastName != value) {
lastName = value;
RaisePropertyChanged("LastName");
RaisePropertyChanged("FullName");
}
}
}
public string FullName {
get {
return firstName + " " + lastName;
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void RaisePropertyChanged(string property) {
if (PropertyChanged != null) {
PropertyChanged(this, new PropertyChangedEventArgs(property));
}
}
}
}
Step 4 - เพิ่มคลาส StudentViewModel อื่นในโฟลเดอร์ ViewModel และวางรหัสต่อไปนี้
using SilverlightMVVMDemo.Model;
using System.Collections.ObjectModel;
namespace SilverlightMVVMDemo.ViewModel {
public class StudentViewModel {
public ObservableCollection<Student> Students {
get;
set;
}
public void LoadStudents() {
ObservableCollection<Student> students = new ObservableCollection<Student>();
students.Add(new Student { FirstName = "Mark", LastName = "Allain" });
students.Add(new Student { FirstName = "Allen", LastName = "Brown" });
students.Add(new Student { FirstName = "Linda", LastName = "Hamerski" });
Students = students;
}
}
}
Step 5 - เพิ่ม Silverlight User Control โดยคลิกขวาที่ Views โฟลเดอร์และเลือก Add New Item….
Step 6- คลิกเพิ่ม ตอนนี้คุณจะเห็นไฟล์ XAML เพิ่มรหัสต่อไปนี้ลงในStudentView.xaml ซึ่งมีองค์ประกอบ UI ที่แตกต่างกัน
<UserControl x:Class = "SilverlightMVVMDemo.Views.StudentView"
xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d = "http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable = "d"
d:DesignHeight = "300" d:DesignWidth = "400">
<Grid x:Name = "LayoutRoot" Background = "White">
<StackPanel HorizontalAlignment = "Left">
<ItemsControl ItemsSource = "{Binding Path=Students}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel Orientation = "Horizontal">
<TextBox Text = "{Binding Path = FirstName, Mode = TwoWay}"
Width = "100" Margin = "3 5 3 5"/>
<TextBox Text = "{Binding Path = LastName, Mode = TwoWay}"
Width = "100" Margin = "0 5 3 5"/>
<TextBlock Text = "{Binding Path = FullName, Mode=OneWay}"
Margin = "0 5 3 5"/>
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</StackPanel>
</Grid>
</UserControl>
Step 7 - ตอนนี้เพิ่มไฟล์ StudentView ลงในไฟล์ MainPage.xaml ไฟล์ดังที่แสดงด้านล่าง
<UserControl x:Class = "SilverlightMVVMDemo.MainPage"
xmlns = "http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x = "http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d = "http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc = "http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:views = "clr-namespace:SilverlightMVVMDemo.Views"
mc:Ignorable = "d"
d:DesignHeight = "576.316" d:DesignWidth = "863.158">
<Grid x:Name = "LayoutRoot" Background = "White">
<views:StudentView x:Name = "StudentViewControl" Loaded = "StudentViewControl_Loaded"/>
</Grid>
</UserControl>
Step 8 - นี่คือการใช้งานไฟล์ Loaded เหตุการณ์ใน MainPage.xaml.cs ซึ่งจะอัปเดตไฟล์ View จาก ViewModel.
using System.Windows;
using System.Windows.Controls;
namespace SilverlightMVVMDemo {
public partial class MainPage : UserControl {
public MainPage() {
InitializeComponent();
}
}
private void StudentViewControl_Loaded(object sender, RoutedEventArgs e) {
SilverlightMVVMDemo.ViewModel.StudentViewModel
studentViewModelObject = new SilverlightMVVMDemo.ViewModel.
StudentViewModel();
studentViewModelObject.LoadStudents();
StudentViewControl.DataContext = studentViewModelObject;
}
}
Step 9 - เมื่อรวบรวมและดำเนินการโค้ดด้านบนคุณจะเห็นผลลัพธ์ต่อไปนี้บนหน้าเว็บของคุณ
UI เทียบกับ ViewModel
หนึ่งในส่วนที่ยากที่สุดของแนวทาง MVVM คือการหาจุดที่เส้นแบ่งควรมา ไม่ชัดเจนเสมอไปว่าของอยู่ที่ไหน
โดยเฉพาะอย่างยิ่งองค์ประกอบอินเทอร์เฟซผู้ใช้บางอย่างมีฟังก์ชันการทำงานซึ่งตามมุมมองที่เข้มงวดควรเป็นเนื้อหาใน ViewModel
โดยทั่วไปไม่ใช่พฤติกรรมทั้งหมดที่นำมาใช้ในไฟล์ View เป็นเช่นนั้น ViewModel เป็นมิตร
สาเหตุส่วนหนึ่งคือไม่มีวิธีมาตรฐานใด ๆ ในการจัดแพ็กเกจพฤติกรรม ViewModel เพื่อใช้ซ้ำโดยเฉพาะอย่างยิ่งหากคุณต้องการใช้สภาพแวดล้อมการออกแบบเช่น Visual Studio หรือ Blend
ข้อดีของ MVVM
MVVM มีข้อดีดังต่อไปนี้ -
การแยกข้อกังวลในการนำเสนอ (View, ViewModel, Model)
ทำความสะอาดโค้ดที่ทดสอบได้และจัดการได้ สามารถรวมตรรกะระดับการนำเสนอในการทดสอบหน่วย
ไม่มีโค้ดหลังโค้ดดังนั้นเลเยอร์การนำเสนอและตรรกะจึงเชื่อมโยงกันอย่างหลวม ๆ
วิธีที่ดีกว่าในการเชื่อมโยงฐานข้อมูล
ข้อเสียของ MVVM
สำหรับ UI ที่เรียบง่าย MVVM อาจเกินความจำเป็น การดีบักจะค่อนข้างยากเมื่อเรามีการผูกข้อมูลที่ซับซ้อน