Модель ответственности MVVM

Это основной вопрос MVVM.

Допустим, у меня есть окно редактора студента, которое позволяет пользователю установить метод оплаты студента (наличными или чеком). Для обеспечения гибкости возможные способы оплаты должны быть получены с сервера, а список зависит от возраста учащегося, который также может быть изменен.

Вопросы:

  1. где следует хранить возможные способы оплаты? Модель или вид модели?

  2. Если модель, когда пользователь меняет возраст, кто должен загрузить новый список способов оплаты?

что модель должна содержать и делать в MVVM?

2 ответа

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

Альтернативный дизайн включает в себя сильные стороны полиморфизма и может выглядеть следующим образом...

public class Model
{
    private readonly List<PaymentMethod> _allPaymentMethods; 
    public Model()
    {
        // get payment types from the db
        // to populate master list
        _allPaymentMethods = new List<PaymentMethod> {new Cash(), new CreditCard()};
    }
    public List<PaymentMethod> GetPaymentMethods(int age)
    {
        List<PaymentMethod> result =
            _allPaymentMethods.Where(q => q.Age == age).ToList();
        return result;
    }
}
public abstract class PaymentMethod
{
    public string Name { get; protected set; }
    public int Age { get; protected set; }
    public abstract void ProcessPayment();
    public override string ToString()
    {
        return Name;
    }
}
public class CreditCard:PaymentMethod
{
    public CreditCard()
    {
        Name = "Credit Card";
        Age = 25;
    }
    public override void ProcessPayment()
    {
        Console.WriteLine("Thanks for using your card");
    }
}
public class Cash:PaymentMethod
{
    public Cash()
    {
        Name = "Cash";
        Age = 22;
    }
    public override void ProcessPayment()
    {
        Console.WriteLine("Thanks for paying cash");
    }
}

Этот пример жестко кодирует два метода: Cash и Credit Card, и каждый класс знает, как выполнять свою работу, полагаясь на наследование для обработки общих атрибутов. Этот подход избегает "переключения" и включает в себя все бизнес-правила и методы в каждом классе. Таким образом, Модель предоставляет только то, что необходимо знать ViewModel, чтобы представить пользователю различные способы оплаты в элементе управления товарами.

Когда пользователь меняет свой возраст, ваша виртуальная машина может обновить список.

Фрагмент кода для виртуальной машины выглядит так...

public class ViewModel :INotifyPropertyChanged
{
    public ObservableCollection<PaymentMethod> Methods { get; set; }
    public ViewModel()
    {
        Model m = new Model();
        Methods = new ObservableCollection<PaymentMethod>(m.GetPaymentMethods(22));
    }
    #region INotifyPropertyChanged Implementation
    public event PropertyChangedEventHandler PropertyChanged;
    protected virtual void OnPropertyChanged(string name)
    {
        var handler = System.Threading.Interlocked.CompareExchange
               (ref PropertyChanged, null, null);
        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(name));
        }
    }
    #endregion
}

Какой бы подход вы ни использовали (перечисление или полиморфизм), практическое правило гласит: "Нужно ли виртуальной машине знать об этом? Могу ли я использовать преимущества ОО наследования и полиморфизма в моей архитектуре?"

Ну, по моему мнению, модель должна содержать список способов оплаты, а виртуальная машина должна содержать список для привязки к представлению. Пример, что я хотел бы сделать, это иметь List<PaymentOptions> на модели и BindingList<PaymentOptions> или же ObservableCollection<PaymentOptions> для ВМ.

Другие вопросы по тегам