Я создаю небольшое приложение для управления гоночными онлайн-лигами.
Для этого у меня будет база данных, которая получает доступ к данным из Интернета и предоставляет доступ к объектам данных через интерфейс. База данных еще не существует, но я создал макет, который использует локальные файлы XML в качестве источника данных.
Небольшой пример для интерфейса лиги:
public interfac ISchedule
{
string Name { get; set; }
List<IRaceSession> Races { get; }
// and some more properties …
IRaceSession AddRace();
void RemoveRace(IRaceSession race);
// and some more Methods …
}
public interface IRaceSession
{
uint RaceId { get; }
DateTime Date { get; set; }
TimeSpan Duration { get; set; }
// and some more properties …
}
Теперь, чтобы получить это в моем шаблоне WPF с MVVM, я создал Модель для каждого объекта, который выставляет база данных, и внедрил там INPC.
* Примечание: ContainerModel<>
и ObservableModelCollection<>
- это классы, которые я создал для обработки обновлений из базы данных, сохраняя при этом INPC без изменений.
public class ContainerModel<T>
{
T Source { get; set; }
public ContainerModel(T source)
{
Source = source;
}
void UpdateSource(T source)
{
// handle updates …
}
}
public class ScheduleModel : ISchedule, ContainerModel<ISchedule>
{
public string Name { get => Source.Name ; set { Source.Name = value; NotifyPropertyChanged(); } }
public ObservableModelCollection<RaceSessionModel, IRaceSession> Races { get; }
List<IRaceSession> ISchedule.Races => Source.Races
public ScheduleModel(ISchedule source) : base(source)
{
Races = new ObservableModelCollection<RaceSessionModel, IRaceSession>(Source.Races);
}
IRaceSession AddRace()
{
Races.Add(// new Race Object);
}
void RemoveRace(IRaceSession race)
{
Races.Remove(// select race object to remove);
}
}
public class RaceSessionModel : IRaceSession, ContainerModel<IRaceSession>
{
public uint RaceId => Source.RaceId;
puglic DateTime Date { get => Source.Date; set { Source.Date = value; NotifyPropertyChanged(); } }
TimeSpan Duration { get => Source.Duration; set { Source.Duration = value; NotifyPropertyChanged(); } }
//--> here come some more logic im not sure About:
TimeSpan DurationHours
{
get => Duration.Hours;
set
{
// set only Hours componennt of Duration
Duration = Duration
.Subtract(Duration.Hours)
.Add(value);
NotifyPropertyChanged();
}
TimeSpan DurationMinutes
{
get => Duration.Minutes;
set
{
// set only Minutes componennt of Duration
Duration = Duration
.Subtract(Duration.Minutes)
.Add(value);
NotifyPropertyChanged();
}
}
Тогда у меня есть viewModel и представление, которое напрямую связывается со свойствами модели.
public class SchedulerViewModel : ViewModelBase //<-- just a Basic implementation of INPC
{
private ScheduleModel _schedule;
public ScheduleModel Schedule { get => _schedule; set { _schedule = value; NotifyPropertyChanged(); } }
public SchedulerViewModel(ScheduleModel schedule)
{
Schedule = schedule;
}
// Commands and other properties communicating with the view
// …
}
Теперь с этим дизайном у меня возникло несколько проблем. Я все еще нахожусь в процессе обдумывания всего шаблона проектирования, и я впервые создаю его с нуля.
Мои модели на самом деле не содержат данных, а только предоставляют свойства из базы данных.
Правильно ли я думаю, что это то, что должен делать ViewModel?
Как вы видите, мои модели также содержат некоторые виды вычислений для свойства Input. Должна ли эта «бизнес-логика» быть вне модели? Или это также было бы лучше поместить в ViewModel?
В конце концов, я сомневаюсь, что я представляю "модели" вообще. Было бы правильно называть их ViewModels, а затем действовать с Объектом из базы данных в качестве модели?
* Edit:
Когда я начал с этого, я прочитал, что для каждого View
вы должны указывать только один ViewModel
, поэтому я создал свои классы вот так. Но я больше не уверен, правильно ли это.