2015-11-06 1 views
2

Вот упрощенный ViewModel:Как далеко отделить бизнес-логику в MVVM

public class EditViewModel : BaseViewModel 
{ 
    private Item _currentItem; 
    public Item CurrentItem 
    { 
     get 
     { return _currentItem; } 
     set 
     { 
      if (_currentItem != value) 
      { 
       _currentItem = value; 
       OnPropertyChanged("CurrentItem"); 
      } 
     } 
    } 

    private ObservableCollection<Property> _itemProperties; 
    public ObservableCollection<Property> ItemProperties 
    { 
     get { return _itemProperties; } 
     set 
     { 
      _itemProperties = value; 
      OnPropertyChanged("ItemProperties"); 
     } 
    } 

    public void AddProperty() //this is called from an ICommand 
    { 
     Property p = new Property{ ItemId = CurrentItem.ItemId };; 
     CurrentItem.Properties.Add(p); 
     ItemProperties.Add(p); 
    } 
} 

То, что я хотел бы сделать, это отделить бизнес-логику здесь в отдельный класс. Он держит все раздражающие шаблоны MVVM в стороне от полезного материала и теоретически должен привести к тому, что код будет преобразован в более проверяемое состояние.

Мы начинаем делать это, создавая отдельные классы «Логика», которые наследуют от BaseViewModel, а затем имеют фактические ViewModels, наследуемые от их логического класса. Итак:

public class EditLogic : BaseViewModel 
{ } 

public class EditViewModel : EditLogic 
{ } 

Тогда логика идет в логическом классе.

Для некоторых бизнес-логик это разделение простое - приятное и чистое. Тем не менее, в приведенном выше примере я не вижу простого способа вытащить этот метод без большого количества ненужного faff. Что-то вроде этого (непроверенные):

public class EditLogic : BaseViewModel 
{ 
    public Property GetNewProperty(Item currentItem) 
    { 
     Property p = new Property{ ItemId = currentItem.ItemId }; 
     currentItem.Properties.Add(p); 
     return p; 
    } 
} 

public class EditViewModel : BaseViewModel 
{ 
    public void AddProperty() //this is called from an ICommand 
    { 
     ItemProperties(GetNewProperty(CurrentItem)) 
    } 
} 

Это, кажется, может вызвать путаницу - так как он полагается на CurrentItem неявно передается по ссылке - и излишне запутанным, чтобы не большой выгоды.

Это, конечно, очень простой пример, который не стоит суетиться. Но это иллюстрирует тот факт, что в MVVM очень просто закончить смешивание кода презентации/привязки с вашей бизнес-логикой ради удобства.

Я могу перенести некоторые свойства из EditViewModel в EditLogic, но тогда мы теряем преимущества разделения этих двух в первую очередь.

Итак: стоит ли вообще этого беспокоиться? Если да, то как далеко мы должны его преследовать? И есть ли какие-либо лучшие методы для поддержания разделения?

+0

Я не уверен, что ваша модель просмотра должна иметь такую ​​бизнес-логику вообще. Это имеет смысл иметь специализированные бизнес-объекты! Ваши бизнес-объекты также могут реализовать NotifyPropertyChange и просто жить в качестве ссылок на вашу модель представления. ... Imaging «EditCustomerViewModel» с бизнес-объектом «Клиент» ... последнее, что ... вы действительно не могли бы выбрать худшие имена свойств и классов для примера. – BenjaminPaul

ответ

2

То, что вы ищете, это услуги.

public interface IPropertyService 
{ 
    Property GetNewProperty(Item currentItem); 
} 

Вы, конечно, потребуется реализация:

public class MyPropertyService : IPropertyService 
{ 
    public Property GetNewProperty(Item currentItem) 
    { 
     //TODO 
    } 
} 

Вы можете впрыснуть эту услугу в конструкторе модели представления в виде зависимости.

public class MyViewModel 
{ 
    private IPropertyService _PropertyService; 

    public MyViewModel(IPropertyService propertyService) 
    { 
     _PropertyService = propertyService; 
    } 

    public void AddProperty() //this is called from an ICommand 
    { 
     Property p = _PropertyService.GetProperty(CurrentItem); 
     CurrentItem.Properties.Add(p); 
     ItemProperties.Add(p); 
    } 
} 

Это гарантирует, что вам не нужно создавать множество базовых классов модели представления для вашей бизнес-логики. Вместо этого инкапсулируйте свою бизнес-логику в сервисы и передайте их в модели просмотра, которые зависят от них.

Смежные вопросы