[MVC] Model?我比較喜歡叫它ViewModel
這篇純粹是個人工作上的感覺,沒啥絕對性。
在MVC的架構中,我們都知道Model跟View有著曖昧的密友關係,
不過有時候在一個View的呈現上可能會使用多的Model組合而成的資料,
這時如果我們把組合Model的邏輯在Controller端硬兜好的話,
那麼Controller的Code就會變的相當多且複雜。
我用下方的例子作說明:
場景:
有一個極簡單的UI畫面須要組合Person和ContactMech兩個Model來呈現個人資料,
建立一個ViewModel來讓Controller端的程式Create,Edit,Show能好維護好閱讀。
首先會有兩個Model
1: //Table: Person 對應的Domain Class
2: public class Person
3: {
4: public string Id { get; set; }
5: public string Name { get; set; }
6: public string Gender { get; set; }
7: public ContactMech ContactMech { get; set; }
8: }
9:
10: //Table: ContactMech 對應的Domain Class
11: public class ContactMech
12: {
13: public string Id { get; set; }
14: public string Mobile { get; set; }
15: public string Email { get; set; }
16: }
再來是我們的主角ViewModel,這邊的Model是一個非常充血的Model,因為他就只為了服務這些同值的View,越充血越好。
1:
2: // 一個充血型的Model,可以幫我們完成很多事情並讓Controller跟View節省很多Code
3: public class PersonInfoModel
4: {
5: // 呈現的View資料是來自兩個Model 定出View所需要用的相關屬性
6: public string Name { get; set; }
7: public string Gender { get; set; }
8: public string Mobile { get; set; }
9: // 可以在屬性上設定相關的驗證如下:Email為必填欄位
10: [Required]
11: public string Email { get; set; }
12: public string PersonId { get; set; }
13:
14: public PersonInfoModel()
15: {
16: // 可利用建構子來初始化
17: }
18:
19: public PersonInfoModel(string id)
20: {
21: // 可利用建構子來初始化 如:
22: Show(id);
23: }
24:
25: public void Insert()
26: {
27: // 新增時要做的事
28: }
29:
30: public void Update()
31: {
32: // 修改時要做的事
33: }
34:
35: public void Save()
36: {
37: // 新增跟修改時的重複程式或共同邏輯可放這
38: }
39:
40: public void MapDomainToModel(string id)
41: {
42: // Show畫面呈現資料時要做的事,如把Model物件map到這個ViewModel上
43: Person person = personService.GetById(id);
44: this.PersonId = person.Id;
45: this.Name = person.Name;
46: this.Gender = person.Gender;
47: this.Mobile = person.ContactMech.Mobile;
48: this.Email = person.ContactMech.Email;
49: }
50: }
ViewModel做了這麼多事,那Controller需要幹什麼?
其實Controller光是要去處理View的Request就已經會讓它變的很複雜了,如:form submit,Ajax Get Post Load等等...
每一個request都要去幫它找合適的對象(Model,ViewModel,Json之類的),然後還要看要Return什麼東西給人家,
若在把ViewModel裡的邏輯都在Controller做的話,不僅寫的人會瘋掉連維護的人也會瘋掉
若以上方的ViewModel的方式的話,Controller就單純多了,如下
1: public partial class PersonInfoController
2: {
3: public ActionResult Show(string id, string cdts)
4: {
5: PersonInfoModel model = new PersonInfoModel(id);
6: return View(model);
7: }
8:
9: public ActionResult Create()
10: {
11: return View();
12: }
13:
14: [HttpPost]
15: public ActionResult Create(PersonInfoModel model)
16: {
17: if (!ModelState.IsValid)
18: {
19: return View(model); //// 不通過驗證
20: }
21: model.Insert();
22: return RedirectToAction("Show", new { id = model.PersonId });
23: }
24:
25: public ActionResult Edit(string id)
26: {
27: PersonInfoModel model = new PersonInfoModel(id);
28: return View(model);
29: }
30:
31: [HttpPost]
32: public ActionResult Edit(PersonInfoModel model)
33: {
34: if (!ModelState.IsValid)
35: {
36: return View(model); //// 不通過驗證
37: }
38: model.Update();
39: return RedirectToAction("Show", new { id = model.PersonId });
40: }
41: }
這樣Controller的Code就乾淨清爽多了,也很容易的知道每個Action在幹什麼,
就算之後可以還會要求在多一個Copy的Action那麼,也只要Controller分配好Model的動作就可以迅速的完成這功能。
以上是個人寫MVC的偏好,感謝您耐心的看完了,希望有幫助到。