Информационни системи - упражнение № 2
TRANSCRIPT
РАЗРАБОТКА НА МНОГОСЛОЙНИ ПРИЛОЖЕНИЯЦветелин Павлов
План на курса
Обща информация, определенияСценарий за разработкаРазработка на базата данни и обектния домейнСъздаване на функционалностите за работа със студентски данни• Разработка на функционалностите за работа с оценки
МОДЕЛ НА ПРЕДМЕТНАТА ОБЛАСТ
Изходен код на проекта• Изтеглете: http://www.uni-ruse.bg/info-sys/lab-2.zip• Премахнете блокировката• Десен бутон -> Properties -> Unblock
• Разархивирайте• Премахнете ограничението „само за четене“• Отворете във Visual Studio• Разкачете проекта от системата за контрол на изходния код
Клас диаграма
Обектът „Оценка“Public Class Score Inherits DomainObject
Private ReadOnly theStudent As Student = Nothing Public ReadOnly Property Student As Student Get Return theStudent End Get End Property
Private theSubject As Subject Public Property Subject As Subject Get Return theSubject End Get Protected Set(value As Subject) theSubject = value End Set End Property
Public Property Value As Double
Public Sub New(aStudent As Student, aSubject As Subject, aValue As Double) theStudent = aStudent theSubject = aSubject Value = aValue End Sub
End Class
Обектът „Нова оценка“Public Class NewScore Inherits Score
Public Shadows Property Subject As Subject Get Return MyBase.Subject End Get Set(value As Subject) MyBase.Subject = value End Set End Property
Public Sub New(aStudent As Student) MyBase.New(aStudent, Nothing, 0) End Sub
End Class
УПРАЖНЕНИЕ № 2Създаване на функционалностите за работа със студентски данни
Скица на потребителския интерфейс
План на упражнението
• Шаблони за проектиране• Шаблонът „Model-View-ViewModel”• Разработка на модел• Разработка на модел на гледка за списъчен изглед• Разработка на списъчен изглед• Разработка на модел на гледка за редакция на студентски данни• Разработка на формуляр за редакция на студентски данни
Шаблони за проектиране
• a.k.a. Design patterns• Рецепти за проектиране• Независими от езика или платформата за програмиране• Най-известните: • Model-View-Controller – MVC• Adapter• Façade• Command• Abstract factory• Singleton
MVVM
MODELМоделът за връзка с базата данни
ILabDBAModelPublic Interface ILabDBAModel
Function GetStudents() As IList(Of Domain.Student) Function GetSubjects() As IList(Of Domain.Subject)
Sub SaveStudent(theStudent As Domain.Student) Sub SaveScore(theScore As Domain.Score)
Sub DeleteStudent(student As Domain.Student) Sub DeleteScore(score As Domain.Score)
End Interface
Entity Framework
Данни за връзка със сървъраСървър vader
Потребителско име InfoSys.Lab
Парола @Test-2012
Комбинация за свиване на кода
Ctrl + M, O
GetStudents Public Function GetStudents() As IList(Of Domain.Student) Implements ILabDBAModel.GetStudents Using orm As New InfoSysEntityModel(theConnectionString)
Dim dbResult As IList(Of Student) = orm.Students.ToList() Dim methodResult As New List(Of Domain.Student)()
For Each aStudent As Student In dbResult Dim translatedStudent As New Domain.Student(aStudent.StudentID)
translatedStudent.FirstName = aStudent.FirstName translatedStudent.LastName = aStudent.FamilyName translatedStudent.PhotoURL = aStudent.PhotoURL
Dim scores As List(Of Score) = aStudent.Scores.ToList() For Each Score As Score In scores Dim translatedSubject As New Domain.Subject(Score.Subject.SubjectName) Dim translatedScore As New Domain.Score(translatedStudent, translatedSubject, Score.Value) translatedStudent.Scores.Add(translatedScore) Next
methodResult.Add(translatedStudent) Next
Return methodResult End UsingEnd Function
Извличане на данни за студенти
Dim dbResult As IList(Of Student) = orm.Students.ToList()
SaveStudent Public Sub SaveStudent(theStudent As Domain.Student) Implements ILabDBAModel.SaveStudent Using orm As New InfoSysEntityModel(theConnectionString)
Dim aStudent As Student Dim isNew As Boolean = False
If TypeOf theStudent Is Domain.NewStudent Then aStudent = New Student() isNew = True Else aStudent = orm.Students.FirstOrDefault(Function(s) s.StudentID = theStudent.StudentID) isNew = False End If
aStudent.StudentID = theStudent.StudentID aStudent.FirstName = theStudent.FirstName aStudent.FamilyName = theStudent.LastName aStudent.PhotoURL = theStudent.PhotoURL
If isNew Then orm.Students.AddObject(aStudent) End If
orm.SaveChanges()
End UsingEnd Sub
Извличане на запис по ключ
aStudent = orm.Students.FirstOrDefault(Function(s) s.StudentID = theStudent.StudentID)
DeleteStudent Public Sub DeleteStudent(student As Domain.Student) Implements ILabDBAModel.DeleteStudent
Using orm As New InfoSysEntityModel(theConnectionString) Dim theStudent As Student = orm.Students.FirstOrDefault(Function(dbStudent) dbStudent.StudentID = student.StudentID)
If theStudent IsNot Nothing Then orm.Students.DeleteObject(theStudent) orm.SaveChanges() Else Throw New ObjectNotFoundException("Студент с такъв факултетен номер не е намерен в базата данни.") End If
End Using End Sub
СПИСЪК СТУДЕНТИИмплементиране на функционалностите за работа със списък от студенти
VIEW MODELМодел на списъчният изглед
Базов модел на гледкаImports System.ComponentModelImports InfoSys.Lab.Models
Public Class ViewModelBase Implements INotifyPropertyChanged
Public Event PropertyChanged(sender As Object, e As PropertyChangedEventArgs) Implements INotifyPropertyChanged.PropertyChanged
Private ReadOnly theModel As ILabDBAModel Protected ReadOnly Property Model As ILabDBAModel Get Return theModel End Get End Property
Public Sub New(aModel As ILabDBAModel) theModel = aModel End Sub
Protected Sub DoNotify(aPropertyName As String) RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(aPropertyName)) End Sub
End Class
Модел на списъчната гледкаImports InfoSys.Lab.Domain
Public Interface IStudentsListViewModel
Property StudentsList As IList(Of Student) Property SelectedStudent As Student
ReadOnly Property RefreshStudentsListCommand As ICommand ReadOnly Property NewStudentCommand As ICommand ReadOnly Property DeleteStudentCommand As ICommand
End Interface
Свойството StudenstList
Public Property StudentsList As IList(Of Domain.Student) Implements IStudentsListViewModel.StudentsList Get Return theStudentsList End Get Set(value As IList(Of Domain.Student)) theStudentsList = value DoNotify("StudentsList") End SetEnd Property
Свойството SelectedStudent Public Property SelectedStudent As Domain.Student Implements IStudentsListViewModel.SelectedStudent Get Return theSelectedStudent End Get Set(value As Domain.Student) theSelectedStudent = value
DoNotify("SelectedStudent") DoNotify("IsSelected")
theMediator.SetStudent(theSelectedStudent) End SetEnd Property
Обработчици на командите
Private Sub whenRefresh() Me.StudentsList = Model.GetStudents()End Sub
Обработчици на командите
Private Function canDelete() As Boolean
Return IsSelected AndAlso Not TypeOf SelectedStudent Is NewStudent
End Function
Обработчици на командите
Private Sub whenDelete() If SelectedStudent IsNot Nothing Then Model.DeleteStudent(SelectedStudent) theMediator.DoRefresh() End IfEnd Sub
Обработчици на командите
Private Sub whenNew() Me.SelectedStudent = New NewStudent()End Sub
VIEWСписъчната гледка
Refresh бутон
<Button Command="{Binding Path=RefreshStudentsListCommand}" Content="Опресни" Margin="8" />
Бутон „Добавяне на студент“
<Button Command="{Binding Path=NewStudentCommand}" Content="Нов" Margin="8" Grid.Column="1" />
Бутон „Изтриване“
<Button Command="{Binding Path=DeleteStudentCommand}" Content="Изтрий" Margin="8" Grid.Column="2" />
Списъчна контрола
<ListBox ItemsSource="{Binding Path=StudentsList}" SelectedItem="{Binding Path=SelectedStudent, Mode=TwoWay}" Grid.ColumnSpan="3" Margin="8" Grid.Row="1" />
StudentsListView.xaml.vb
Public Class StudentsListView
Public Sub New(theVM As IStudentsListViewModel)
InitializeComponent() Me.DataContext = theVM
End Sub
End Class
Application.xaml.vbPrivate Sub WhenStart() Handles Me.Startup Dim theModel As New LabDBModel(“vader", "InfoSys.Lab.1", "InfoSys.Lab", "@Test-2012") Dim theMediator As New MainWindowMediator()
Dim theMainWindowViewModel As New MainWindowViewModel( Nothing, Nothing, Nothing, Nothing ) Dim theMainWindow As New MainWindow(theMainWindowViewModel)
theMainWindow.Show() Me.MainWindow = theMainWindow End Sub
Бази данни
InfoSys.Lab.DB.1-1...
InfoSys.Lab.DB.3-9
Добавяне на списъчната гледка
Dim theStudenstListViewModel As New StudentsListViewModel( theModel, theMediator)
theMediator.RegisterCanRefresh(theStudenstListViewModel)
Dim theStudentsListView As New StudentsListView( theStudenstListViewModel)
Инжектиране в основния прозорец
Dim theMainWindowViewModel As New MainWindowViewModel (
Nothing, Nothing, Nothing, theStudentsListView
)
РЕДАКЦИЯ НА СТУДЕНТИмплементиране на функционалностите за редакция на информацията на студент
VIEW MODELМодел на формуляра
Модел на формуляраImports InfoSys.Lab.Domain
Public Interface IStudentEditViewModel
Property StudentID As String
Property FirstName As String Property LastName As String
Property PhotoURL As String
ReadOnly Property isNew As Boolean Property isChanged As Boolean
ReadOnly Property SaveStudent As ICommand
End Interface
Свойството StudentProtected Property Student As Domain.Student Get Return theStudent End Get Set(value As Domain.Student) theStudent = value isChanged = False
DoNotify("FirstName") DoNotify("LastName") DoNotify("StudentID") DoNotify("PhotoURL") DoNotify("isNew") DoNotify("IsSelected") End SetEnd Property
Обработчици на командите
Private Sub WhenSaveStudent() Model.SaveStudent(Student) theMediator.DoRefresh()End Sub
VIEWГледка на формуляра
Етикети
<Label Content="Факултетен номер" Margin="8"/><Label Content="Собствено име" Margin="8" Grid.Row="1"/><Label Content="Фамилия" Margin="8" Grid.Row="2"/>
Поле за факултетен номер
<TextBox Text="{Binding Path=StudentID, Mode=TwoWay}" IsEnabled="{Binding Path=isNew}" Grid.Column="1" Margin="8" TextWrapping="Wrap" MinWidth="60" />
Поле за собствено име
<TextBox Text="{Binding Path=FirstName, Mode=TwoWay}" Grid.Column="1" Margin="8" TextWrapping="Wrap" Grid.Row="1" Grid.ColumnSpan="2" />
Поле за фамилия
<TextBox Text="{Binding Path=LastName, Mode=TwoWay}" Grid.Column="1" Margin="8" TextWrapping="Wrap" Grid.Row="2" Grid.ColumnSpan="2" />
Бутон за запазване
<Button Command="{Binding Path=SaveStudent}" IsEnabled="{Binding Path=isChanged}" Content="Запази" Grid.Column="2" Grid.Row="3" Margin="8" VerticalAlignment="Top" />
StudentEditView.xaml.vb
Public Class StudentEditView
Public Sub New(theVM As IStudentEditViewModel)
InitializeComponent() Me.DataContext = theVM
End Sub
End Class
Application.xaml.vbDim theStudentEditViewModel As New StudentEditViewModel( theModel, theMediator)
theMediator.RegisterInterestedInStudent( theStudentEditViewModel)
Dim theStudentEditView As New StudentEditView( theStudentEditViewModel)
Инжектиране в основния прозорец
Dim theMainWindowViewModel As New MainWindowViewModel (
Nothing, Nothing, theStudentEditView, theStudentsListView
)
КРАЙ НА УПРАЖНЕНИЕ № 2Създаване на функционалностите за работа със студентски данни