2012-06-26 16 views
5

Tôi sử dụng Automapper hoặc ánh xạ theo cách thủ công, không đóng vai trò nào.Tôi vẫn còn do dự khi sử dụng ViewModels thay vì Mô hình cho Chế độ xem

Tất cả dữ liệu cho ReleaseViewModel phải là lần đầu tiên trong Bản phát hành vì nó được điền vào lớp truy cập dữ liệu với nó. 90% mô hình của tôi là như thế này. Tại sao phí tổn sao chép tất cả mọi thứ?

Còn nguyên tắc và kỹ thuật quá mức của KISS thì sao?

Tất nhiên mọi công cụ cho nhiệm vụ thích hợp của nó, nhưng rất thường xuyên tôi đọc trên SO mà không sử dụng ViewModels trong asp.net mvc là một NO-GO.

Nơi vẽ đường kẻ? Tôi có nên sử dụng ViewModels khi họ phân biệt với 50%, 75% hoặc 99% từ các mô hình của tôi không?

Tôi có một mô hình phát hành:

public class Release 
    {  
     public int Id { get; set; }  
     public string Name { get; set; } 
     public string Author { get; set; } 
     public DateTime CreatedAt { get; set; } 
     public int FailedTestsCount { get; set; } 
     public int SucceededTestsCount { get; set; } 
     public int SumTestsCount 
     { 
      get 
      { 
       return SucceededTestsCount + FailedTestsCount; 
      } 
     } 
     public int SumTestingTime { get; set; } 
    } 

một ReleaseViewModel viewmodel:

public class ReleaseViewModel 
{ 
    [HiddenInput(DisplayValue = false)] 
    public int Id { get; set; } 

    [Required(ErrorMessage = "Name must not be empty.")] 
    [StringLength(30, ErrorMessage = "Enter max. 30 chars for a name.")] 
    [Remote("ReleaseExists", "Release", ErrorMessage = "This name already exists.")] 
    public string Name { get; set; }  
    public string Author { get; set; }  
    public DateTime CreatedAt { get; set; }  
    public int FailedTestsCount { get; set; }  
    public int SucceededTestsCount { get; set; }  
    public int SumTestsCount 
    { 
     get 
     { 
      return SucceededTestsCount + FailedTestsCount; 
     } 
    } 

    public int SumTestingTime { get; set; } 
} 
+0

Lớp phát hành của bạn có phải là DTO hay là đối tượng miền có chức năng? – Jupaol

+0

đối tượng miền của nó. Tôi không có nhiều lớp để có nhu cầu cho một dto. – Pascal

+0

Tại sao bạn không muốn Tên được yêu cầu và ít hơn 30 char trong mô hình miền của bạn? Mặc dù mô hình miền của bạn không thể hiển thị thông điệp đẹp cho người dùng, nhưng nó vẫn có thể từ chối xử lý nếu ModelState.IsValid là sai. Ít nhất đó là cách tôi nghĩ bạn nên làm điều đó, nhưng tôi là một newbie –

Trả lời

5

ViewModel là nội dung dành cho VIEW. phần lớn thời gian nó giống với mô hình thực thể của bạn. Nhưng không phải lúc nào.

Xem ví dụ của bạn. Trong số ViewModel, bạn có thuộc tính Remote và một số thuộc tính Xác thực. Vì vậy, kiểm tra Tên từ xa này là thứ bạn thêm vào để mang lại trải nghiệm người dùng tốt hơn cho Người dùng của bạn. Nó dành riêng cho Chế độ xem.

Một trường hợp khác mà bạn cần một ViewModel là dành cho màn hình nơi bạn có nhiều mô hình liên quan. Ví dụ: Bạn có một thực thể là User Thực thể và một thực thể là Project và bạn muốn cung cấp màn hình có thể thêm Dự án vào Người dùng. Vì vậy, trong trường hợp này, bạn có thể tạo chế độ xem để xử lý

public class ProjectToUserVM 
{ 
    public int UserId { set;get;} 
    public string UserName { set;get;} // i want to display only name of user! 
    public int ProjectID { set;get;} 
    public IEnumerable<SelectListItem> Projects { set;get} 
} 

Không sử dụng Chế độ xem dành cho tất cả các đối tượng mô hình của bạn. Tạo nó khi VIEW của bạn thực sự cần nó. Tôi sử dụng các đối tượng thực thể Model của tôi trực tiếp trong một số khung nhìn mà không tạo một viewmodel đôi khi vì các đối tượng đó giống hệt nhau. Ví dụ: Quốc gia/Tiểu bang/Thành phố (Tra cứu dữ liệu bảng.Nó Thêm/Chỉnh sửa)

+0

có nghĩa là nhận xét "tôi muốn chỉ hiển thị tên người dùng!" ?? Và có xác thực từ xa thuộc về không gian tên MVC, nhưng HEY tôi đang làm một ứng dụng mvc để khớp nối này hoàn toàn OK. Đôi khi tôi có cảm giác lớp SelectListItem là đối số hàng đầu của các máy bay chiến đấu viewmodel để cho chúng tôi biết rằng chúng ta cần một viewmodel khác mô hình được ràng buộc chặt chẽ với mvc, nhưng lại là một ứng dụng MVC của nó. Tôi nghĩ rằng 99% của tất cả các ứng dụng doanh nghiệp không tái sử dụng tên miền của họ trong một ứng dụng khác như winforms/wpf do đó không gian tên web.mvc là tốt trong mô hình theo ý kiến ​​của tôi. – Pascal

+0

Tôi thích nhận xét này nhiều nhất: "Tạo nó khi VIEW của bạn thực sự cần nó." Tôi sẽ làm điều đó và khi tôi làm điều đó rất hiếm khi tôi làm điều đó bằng tay. Ít chi phí lắp ráp hơn. Ít khớp nối ;-) – Pascal

+0

@Pascal: Nhận xét đó có nghĩa là, Trong ViewModel của tôi, tôi sẽ có các thuộc tính tuyệt đối cần thiết trong quan điểm của tôi. Không phải tất cả các thuộc tính của mô hình của tôi (cột bảng) – Shyju

1

ViewModels của tôi chỉ đơn giản là quấn một mô hình, và đại biểu đến nó 90% thời gian. Họ chỉ có hành vi của riêng họ khi tôi cần phải thay đổi một cái gì đó về hành vi của mô hình cho một trường hợp sử dụng xem cụ thể. Để máy ảo thực sự dễ dàng thêm hành vi chỉ cần thiết cho mục đích hiển thị, đặc biệt nếu hành vi đó sẽ ảnh hưởng đến mô hình kiên trì của bạn (ví dụ: thêm thuộc tính mà bạn không muốn duy trì). Nó cũng đáng chú ý rằng nó là khá có thể sử dụng một công cụ IoC như Castle hoặc SpringFramework.net để tạo ra các hành vi chuyển tiếp mặc định trên bay, giảm số lượng mã mà bạn cần phải viết bằng tay. Điều này làm giảm "chi phí nhân bản" khá đáng kể, do đó, nó không phải là xấu như nó có vẻ lúc đầu tiên.

+0

"ví dụ: thêm thuộc tính mà bạn không muốn tồn tại)." sau đó không tồn tại chúng ?! Tôi không sử dụng ORMapper. "Chế độ xem của tôi chỉ đơn giản là bao bọc một Mô hình và ủy quyền cho nó 90% thời gian." Bạn làm điều đó giống như trong mô hình MVVM? Điều đó làm tôi ngạc nhiên. http://stackoverflow.com/questions/11213644/is-the-viewmodel-in-asp-net-comparable-to-the-viewmodel-in-wpf – Pascal

+0

Tôi đoán tôi sử dụng một cái gì đó như MVVM. Tôi đã luôn luôn có một chút của một vấn đề với 'tinh khiết' MVC, và tôi thấy mô hình MVVM tự nhiên hơn (ngay cả đối với ASP.NET MVC). YMMV :-) –

2

Tại sao phải sao chép mọi thứ?

Trước hết, bạn có thể nghĩ Tôi sao chép mã, nhưng thực tế là bạn không, trong trường hợp bạn đang làm việc đó, bạn có một vấn đề thiết kế nghiêm trọng

tôi đã tìm thấy có một nguyên tắc mà khi bạn không tuân theo nó, nó thực sự là gốc rễ của mọi điều ác: SRP (Nguyên tắc Trách nhiệm Đơn)

Có lẽ vì bạn chưa tìm thấy vấn đề, hoặc có thể, bạn có và bạn vừa vá mã của bạn. Trách nhiệm của đối tượng miền của bạn hoàn toàn khác với trách nhiệm trình bày dữ liệu cho người dùng.

Mô hình trong MVC, phải là lớp đại diện cho tất cả dữ liệu mà chế độ xem cần hiển thị và không có gì khác. Bạn cần điền mô hình này với dữ liệu từ miền của bạn. (hoặc trong một kiến ​​trúc CQRS, từ các dịch vụ truy vấn của bạn)

Nếu bạn theo một kiến ​​trúc CQRS (ít nhất là cơ bản, bạn không cần phải thực hiện tìm kiếm sự kiện hay sử dụng xe buýt dịch vụ.), điều này sẽ rõ ràng hơn đối với bạn, trách nhiệm của đối tượng truy vấn hoàn toàn khác với đối tượng lệnh (một hành động từ tên miền của bạn)

Tôi nghĩ rằng bạn đã hiểu sai nguyên tắc KISS, trong khi nó nói về kỹ thuật quá mức của bạn mã hoặc YAGNI, điều đó không có nghĩa là bạn phải sử dụng lại mọi thứ trong đơn đăng ký của bạn

Tin tôi đi, tôi đã học cách này xấu = (, mã duy nhất nên được sử dụng lại là mã cơ sở hạ tầng, khi nói về mã miền, tốt hơn nên luôn theo dõi SRP

+0

"điều đó không có nghĩa là bạn phải sử dụng lại mọi thứ trong ứng dụng của bạn" KHÔ. – Pascal

+0

Bạn không vi phạm nguyên tắc DRY ... Tôi đã ở đó ... bạn chỉ cần hiểu vai trò ** ** mỗi thành phần đang phát. Ngay sau khi bạn hiểu điều này, và ngay sau khi bạn học cách ** làm cho vai trò rõ ràng ** bạn sẽ thấy ánh sáng ở cuối đường hầm. Đọc một số bài báo từ Udi Dahan. Tôi đã có cuộc thảo luận này nhiều lần và gốc luôn giống nhau ... thiếu lí thuyết thiết kế. Và nếu bạn khăng khăng làm theo cách tiếp cận này, bạn sẽ học (như tôi đã làm) điều này là xấu ... Tôi nghĩ bạn đang rơi vào hội chứng đạn _Silver ..._ – Jupaol

+0

Tôi biết tại sao bạn nói điều này không phá vỡ DRY. Bởi vì bạn "thay thế" DRY bằng SRP tại đây. CÓ cách tiếp cận ViewMOdel LUÔN LUÔN là những gì SRP yêu cầu. NHƯNG Tôi thích giữ cho nó đơn giản, để giữ cho nó thực tế và giữ nó theo yêu cầu hiện tại. Bộ luật sạch sẽ nói không kỹ sư nếu cơ hội không phải là 90% mà bạn cần nó. Đây là thực tế cuộc sống thực tế bạn hiểu? Tôi nghĩ bạn mang nó quá cực đoan. Rằng bạn thực sự học được cách xấu bạn phải thực sự đã có một ứng dụng doanh nghiệp lớn.Chúng tôi có một ứng dụng 150K LOC asp.net/wcf ở đây nhưng gần như không cần cho chế độ xem. – Pascal

0

Tôi thứ hai mọi thứ Shyju nói, đặc biệt là phần về "khi bạn cần nó ".

Nếu bạn có một dự án rất đơn giản, nơi các lớp EntityModel của bạn nằm trong cùng một thư viện với các lớp ViewModel của bạn, bạn có thể không cần phải tách riêng ViewModel và có thể từ bỏ chúng. Tôi không nghĩ rằng bất kỳ thông tin thông minh nào sẽ cho bạn biết "bạn đã làm điều này sai vì bạn đang sử dụng các lớp thực thể cho các kiểu xem của bạn, dumass". Chúng tôi không biết ngữ cảnh của ứng dụng của bạn là gì. Nó có thể hoàn toàn thích hợp trong trường hợp của bạn.

Một số người trong chúng ta định nghĩa EntityModels trong một hội đồng không phải web - chỉ là một thư viện lớp đơn giản biên dịch thành một DLL - cho các dự án lớn hơn. Trong trường hợp này, chúng ta thường chỉ cần áp dụng các thuộc tính đặc biệt cho khung nhìn, chẳng hạn như RemoteAttribute và HiddenInputAttribute trong câu hỏi ví dụ của bạn. Tuy nhiên để làm điều này mà không cần sử dụng một lớp viewmodel riêng biệt có nghĩa là chúng ta phải thêm tham chiếu đến System.Web.Mvc.dll vào thư viện EntityModel, trong khi thực tế rằng thư viện không có gì khác để làm với web. Chỉ cần nhớ rằng khi bạn đang sử dụng lại các lớp EntityModel trong các dự án web của bạn (tức là sử dụng chúng như cả mô hình lưu trữ và mô hình trình bày), bạn đang tạo ra một sự kết hợp chặt chẽ hơn giữa các khía cạnh web của dự án và các khía cạnh kinh doanh của dự án của bạn. Nếu bạn có thể biện minh cho điều này vì chi phí/ngân sách, thời gian, đối tượng mục tiêu, phạm vi hoặc các ràng buộc khác, thì hãy làm điều đó và bỏ qua các nhà phê bình của bạn vì họ không nhìn thấy bức tranh lớn như bạn.

0

nếu lớp Phát hành của bạn triển khai INotifyPropertyChanged và tất cả nội dung khác bạn cần cho chế độ xem của mình (xác thực, lệnh, ...) thì bạn không phải sử dụng chế độ xem.nhưng nếu không ...

+0

Lớp Phát hành của tôi được sử dụng trong ứng dụng asp.net mvc. Tại sao nên có INotifyPropertyChanged? – Pascal

+0

oh xin lỗi đã không thấy rằng không có thẻ WPF – blindmeis

Các vấn đề liên quan