這是一個基本的MVVM問題。MVVM模型責任
假設我有一個學生編輯窗口,允許用戶設置學生的付款方式(現金或支票)。爲了靈活性,必須從服務器檢索可能的支付方法,並且該列表根據學生的年齡而變化,這也可以改變。
的問題是:
應該在哪裏存放可能支付方法?模型還是視圖模型?
if model,當用戶更改年齡誰應該下載新的付款方式列表?
MVVM應該包含什麼模型?
這是一個基本的MVVM問題。MVVM模型責任
假設我有一個學生編輯窗口,允許用戶設置學生的付款方式(現金或支票)。爲了靈活性,必須從服務器檢索可能的支付方法,並且該列表根據學生的年齡而變化,這也可以改變。
的問題是:
應該在哪裏存放可能支付方法?模型還是視圖模型?
if model,當用戶更改年齡誰應該下載新的付款方式列表?
MVVM應該包含什麼模型?
那麼,在我看來,模型應該包含支付方法的列表,而虛擬機應該包含一個列表綁定到視圖。例如,我要做的是在模型上有List<PaymentOptions>
,對於VM有BindingList<PaymentOptions>
或ObservableCollection<PaymentOptions>
。
嗨,我更新了問題以使付款方式變爲動態 – LostInComputer
您仍然可以擁有付款方式列表,並且這些付款方式擁有適合年齡的財產嗎?然後在VM中選擇列表中的項目。示例: List
該模型是容納付款方法和與每種方法相關聯的業務規則的邏輯地點。一種方法是使用描述每種支付方法的枚舉,並使用'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");
}
}
此示例硬編碼兩種方法:現金及信用卡,並且每一類都知道該怎麼做了工作,而依靠繼承來處理共同的屬性。這種方法避免了「轉換」,並封裝了每個類中的所有業務規則和方法。因此,該模型只公開ViewModel需要知道的內容,以便在項目控件中向用戶展示各種支付方法。
當用戶更改其年齡時,您的VM可以刷新列表。
的VM代碼片斷看起來像......
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
}
無論接近你使用(無論是枚舉或多態性),經驗法則是「是否VM絕對需要知道嗎?能我將繼承和多態的OO優勢用於我的架構?「
此模型是否還包含學生屬性或者是由VM管理的自己模型中的學生? – LostInComputer
@LostInComputer,我嘗試在我的設計中實現高水平的隔離,因爲它簡化了測試和嘲諷。所以我會對學生使用相同的方法,即將業務規則放入模型中並儘可能少地暴露給虛擬機。單元測試模型,並將其模擬出來以測試虛擬機。 –
那麼誰來決定爲特定學生選擇的支付方式是否有效,服務器還是學生本身? –