Best Practices for ASP.NET MVC: Model (Phần 1)


Bài viết sau đây được dịch từ http://blogs.msdn.com/b/aspnetue/archive/2010/09/17/second_2d00_post.aspx bởi Đào Hải Nam.

ASP.NET MVC đã và đang trở nên phổ biến, với liên tiếp các phiên bản 1, 2, 3 và 4 (sẽ ra mắt cùng với .NET 4.5), ASP.NET MVC đã chứng tỏ sức mạnh của nó. Những ưu điểm của ASP.NET MVC, bao gồm cả của mô hình MVC là: phân tách rõ ràng các phần M-V-C, cung cấp nhiều cơ chế xử lý request khác nhau, dựa trên ASP.NET – vốn đã rất mạnh mẽ, hỗ trợ nhiều view engine, có cơ chế định tuyến (routing) mềm dẻo, giúp người phát triển có thể tạo các URL thân thiện người dùng và SEO…

Bài viết sau cung cấp các khuyến nghị giúp nhà phát triển có thể sử dụng ASP.NET MVC một cách đúng đắn và phù hợp nhất.

Người dịch: Đào Hải Nam

[Bài viết này dựa trên một tài liệu của tác giả Ben Grover (một nhà phát triển cấp cao từ Microsoft). Chúng tôi dự định sẽ đưa những thông tin này vào phần tài liệu MVC 3 trên trang MSDN. Chúng tôi hi vọng được nghe những phản hổi  và mong chờ bất kỳ góp ý nào từ phía các bạn]

Bài viết này giới thiệu một tập các hướng dẫn lập trình nhắm đến các lập trình viên ASP.NET MVC. Tất nhiên, bạn, với tư cách là nhà phát triển sẽ vẫn là người quyết định cuối cùng trong việc chọn hướng dẫn nào phù hợp nhất.

Các khuyến nghị trong việc tạo Model

Phần này nói về việc tạo các model. Các định nghĩa model này bao gồm business logic (cách các đối tượng hoạt động và quan hệ), validation logic (đâu là giá trị hợp lệ của một đối tượng), data logic (các đối tượng được lưu trữ như thế nào) và session logic (trạng thái của người dùng bên trong ứng dụng).

Nên: Tách model ra một project riêng và tạo một assembly riêng.

Với các ứng dụng có mô hình dữ liệu lớn và phức tạp, sẽ là một ý hay nếu bạn tạo một assembly riêng cho model để tránh việc lẫn lộn với các thành phần khác. Bạn sau đó có thể tham chiếu đến assembly này trong ứng dụng ASP.NET MVC.

Nên: đặt tất cả business logic trong model.

Nếu đặt tất cả business logic bên trong model, bạn sẽ bảo vệ view và controller khỏi việc phải tạo các quyết định liên quan đến quy tắc xử lý dữ liệu (business logic). Bạn cũng sẽ có được thêm những lợi ích sau:

  • Giảm việc trùng lắp các business logic.
  • View dễ đọc hơn vì không chứa các quy tắc xử lý.
  • Việc kiểm lỗi các quy tắc xử lý cũng sẽ độc lập với model.

Ví dụ, nếu bạn có một yêu cầu hiển thị tên người dùng với họ đứng trước, bạn có thể đặt nó trong view như sau:

<% if (String.Compare((string)TempData["displayLastNameFirst"], "on") == 0)
       { %>
        Welcome, <%= Model.lastName%>, <%= Model.firstName%>
    <% }
       else
       { %>
        Welcome, <%= Model.firstName%> <%= Model.lastName%>
    <% } %>

Tuy nhiên, bạn sẽ phải lặp lại việc trên trong tất cả các nơi cần hiển thị theo cùng cách. Thay vì vậy, bạn có thể đặt một quy tắc “hiển thị họ trước” trong model bằng cách thêm một thuộc tính giống như sau:

public string combinedName
{
    get
    {
        return (displayLastNameFirst ? lastName + " " + firstName : firstName + " " + lastName);
    }
    private set
    {
        ;
    }
}

Như vậy, view của bạn sẽ đơn giản như sau:

<% Welcome, <%= Model.combinedName %> %>

Nên: đặt tất cả các quy tắc xác định giá trị hợp lệ của dữ liệu bên trong model.

Tất cả các dữ liệu được nhập vào đều phải được kiểm tra tại model. Việc kiểm tra này tuy có thể thực hiện từ phía client, với mục đích tăng hiệu suất. Nhưng nếu thực hiện tại client, việc nó có thể bị bỏ qua hoặc xử lý theo cách không mong muốn (với một công cụ nào đó, kiểu như Fiddler).

Bạn có thể dùng ModelState để thêm các quy tắc kiểm tra. Ví dụ sau cho thấy cách thêm các phép kiểm tra dữ liệu vào ModelState một cách tường minh:

if (String.IsNullOrEmpty(userName))
{
   ModelState.AddModelError("username", Resources.SignUp.UserNameError);
}

Tuy nhiên, với .NET Framework, System.ComponentModel.DataAnnotations được khuyên dùng để làm điều này. Nó cho phép thêm các attribute vào cho các thuộc tính của lớp model, giống ví dụ sau:

public class User
{
   [Required(ErrorMessageResourceName = "nameRequired", ErrorMessageResourceType = typeof(Resources.User))]
   public String userName { get; set; }
       ...
}

Nên: định nghĩa interface cho lớp truy cập dữ liệu

Bạn nên tạo một interface với các phương thức cung cấp chức năng truy cập dữ liệu. Điều này cho phép giảm phụ thuộc giữa các thành phần trong thiết kế chương trình.

Bạn có thể cân nhắc việc dùng Entity Framework hay LINQ to SQL để tạo tầng truy cập dữ liệu. Cả hai Entity Framework và LINQ to SQL để cho phép sử dụng các Stored Procedure.

Nên: đặt tất cả session logic trong model.

Sẽ là vượt quá khỏi phạm vi của bài viết này nếu muốn nói sâu về một số kỹ thuật lưu trữ trạng thái session trong model. Ban đầu, ta chỉ xem sơ qua một số cách có thể dùng để lưu trạng thái session:

Kỹ thuật Ưu điểm Nhược điểm
Lưu ngay trong tiến trình Không phải cài đặt gì thêm. Không dùng được nếu ứng dụng web cần được mở rộng ra (nhiều server).
Dùng dịch vụ lưu trữ session Dịch vụ chạy độc lập trên mỗi máy tính trong web farm.
Nhanh hơn cách dùng CSDL.
Dữ liệu trong session bị mất nếu dịch vụ bị tắt.
Dùng CSDL Dữ liệu trong session được toàn vẹn. Chậm hơn các cánh trên. Chi phí quản lý tương đối cao.

4 thoughts on “Best Practices for ASP.NET MVC: Model (Phần 1)

  1. Pingback: Best Practices for ASP.NET MVC: View (Phần 2) « Đào Hải Nam

  2. Pingback: Best Practices for ASP.NET MVC: Controller (Phần 3) « Đào Hải Nam

  3. Pingback: Blog chi sẽ thủ thuật, khinh nghiệm về công nghệ thông tin

  4. thầy Nam ơi . Thầy làm 1 ví dụ về session đăng nhập trong asp.net mvc cho em với . Em mơ hồ về phần này . Thank thầy

Gửi phản hồi

Mời bạn điền thông tin vào ô dưới đây hoặc kích vào một biểu tượng để đăng nhập:

WordPress.com Logo

Bạn đang bình luận bằng tài khoản WordPress.com Log Out / Thay đổi )

Twitter picture

Bạn đang bình luận bằng tài khoản Twitter Log Out / Thay đổi )

Facebook photo

Bạn đang bình luận bằng tài khoản Facebook Log Out / Thay đổi )

Google+ photo

Bạn đang bình luận bằng tài khoản Google+ Log Out / Thay đổi )

Connecting to %s