Kiến trúc / phân lớp dự án .NET MVC


11

Khi lập kế hoạch kiến ​​trúc cho một ứng dụng web MVC quy mô lớn, làm thế nào để bạn thực hiện các lớp để được tách rời càng tốt và dễ kiểm tra? (về cơ bản tuân theo các thực tiễn tốt nhất) Giả sử tôi đang sử dụng mã trước tiên khi truy cập dữ liệu của mình.

Tôi đấu tranh với những gì để định nghĩa "logic kinh doanh" là và cách nó có nghĩa là tương tác với lớp dữ liệu. Lấy một ứng dụng bán xe làm ví dụ, logic kinh doanh có phải là các lớp thực hiện các nhiệm vụ như tính toán biên độ thuế cho các phương tiện nhất định, so sánh số liệu thống kê dặm trên mỗi gallon vv? Đối với các thực thể kinh doanh (ví dụ: Ô tô, Vans, Xe máy) tôi sẽ đặt chúng trong lớp dữ liệu cùng với DataContextlớp của tôi .

Ngoài ra, điều gì sẽ tạo nên logic ứng dụng trái ngược với kinh doanh - Tôi đoán những thứ như xác nhận đầu vào của phiên / người dùng?

Vì vậy, ví dụ, bộ điều khiển ô tô có thể trả về kết quả hành động / chế độ xem liệt kê mười ô tô hàng đầu được lọc theo loại và mpg tốt nhất. Vì vậy, giả sử tôi đã ICarRepositorytiêm 'carRepo' vào bộ điều khiển của mình (sử dụng mẫu kho / DI), tôi lọc các ô tô của mình từ một tham số phương thức hành động, vdvar cars = carRepo.getCarsByType("hatchback");

Vì vậy, tôi đã giữ kiến ​​thức truy cập dữ liệu ra khỏi bộ điều khiển của mình bằng kho lưu trữ, bây giờ để giữ logic nghiệp vụ ra khỏi bộ điều khiển bằng mô hình miền - var result = new MpgCalculator (ô tô); - Giả sử tôi cần lớp máy tính vì nó cần thực hiện logic bổ sung để tính toán hiệu quả nhiên liệu tốt nhất, hơn là chỉ tải / lọc các thực thể từ DB. Vì vậy, bây giờ tôi có một bộ dữ liệu cho chế độ xem của mình để hiển thị sử dụng kho lưu trữ để truy xuất từ ​​lớp truy cập dữ liệu và đối tượng cụ thể của miền để xử lý và thực hiện các tác vụ liên quan đến kinh doanh trên dữ liệu đó.

Tôi có đang phạm sai lầm ở đây không? chúng ta vẫn cần sử dụng mẫu kho lưu trữ hay tôi chỉ có thể viết mã trên một giao diện để tách riêng ORM và kiểm tra? Trong chủ đề này, vì dbcontext truy cập dữ liệu cụ thể của tôi nằm trong lớp dữ liệu, nên các định nghĩa giao diện sẽ đi vào lớp miền / doanh nghiệp có nghĩa là nếu công nghệ truy cập dữ liệu bị thay đổi, các lớp khác của tôi không bị ảnh hưởng?

Từ những gì tôi đã nghiên cứu cho đến nay cấu trúc của tôi trông như thế này:

Ứng dụng Internet MVC -> Dự án internet tiêu chuẩn - các mô hình ở đây là ViewModels

Lớp Miền / Doanh nghiệp -> các lớp / mô hình cụ thể cho doanh nghiệp mà bộ điều khiển có thể sử dụng để xử lý các thực thể miền từ lớp dữ liệu trước khi chuyển sang các khung nhìn liên quan

Kho lưu trữ trừu tượng cần thiết? -> Tôi nghe nhiều tranh luận về vấn đề này, đặc biệt là khi sử dụng ORM

Lớp dữ liệu -> Các lớp thực thể (Ô tô, Van, Xe máy), DbContext - Lớp công nghệ truy cập dữ liệu cụ thể

Câu trả lời:


26

Bạn đã có rất nhiều phần chuyển động trong câu hỏi của bạn, chạm vào rất nhiều khái niệm, nhưng đây là lời khuyên cơ bản của tôi khi nói về cách nghĩ về một ứng dụng MVC quy mô từ trung bình đến lớn:

Trình bày <---> Logic nghiệp vụ <---> Truy cập dữ liệu

Thứ nhất, tốt nhất không nên nghĩ ứng dụng này là "ứng dụng MVC". Đây là một ứng dụng sử dụng mẫu MVC làm thành phần trình bày. Suy nghĩ về nó theo cách này sẽ giúp bạn tách biệt mối quan tâm logic kinh doanh của bạn khỏi mối quan tâm trình bày của bạn . Có lẽ các ứng dụng nhỏ sẽ tích hợp mọi thứ để truy cập cơ sở dữ liệu vào cấu trúc MVC, nhưng nó sẽ nhanh chóng trở thành không thể áp dụng cho một ứng dụng từ trung bình đến lớn.

MVC (Trình bày)

Trong ứng dụng của bạn, thành phần ASP.NET MVC sẽ xử lý việc chuyển đổi dữ liệu kinh doanh cho mục đích hiển thị (Mô hình), hiển thị giao diện người dùng (Chế độ xem) và các vấn đề giao tiếp như định tuyến, xác thực, ủy quyền, xác thực yêu cầu, xử lý phản hồi và như (Bộ điều khiển). Nếu bạn có mã làm một cái gì đó khác, thì nó không thuộc về thành phần MVC .

Kho lưu trữ / ORM (Truy cập dữ liệu)

Cũng trong ứng dụng của bạn, lớp truy cập dữ liệu nên được quan tâm với việc truy xuất và lưu trữ dữ liệu liên tục. Thông thường đó là ở dạng cơ sở dữ liệu quan hệ, nhưng có nhiều cách khác để dữ liệu có thể được duy trì. Nếu bạn có mã không đọc hoặc lưu trữ dữ liệu liên tục, thì nó không thuộc về lớp dữ liệu . Tôi đã chia sẻ suy nghĩ của mình về cuộc thảo luận ORM / Kho lưu trữ trước đây về SO, nhưng để tóm tắt lại, tôi không coi ORM giống như một Kho lưu trữ, vì nhiều lý do.

Logic kinh doanh

Vì vậy, bây giờ bạn có lớp trình bày (MVC) và lớp dữ liệu của bạn (kho lưu trữ hoặc ORM) ... Mọi thứ khác là lớp logic kinh doanh (BLL) của bạn. Tất cả mã của bạn quyết định lấy dữ liệu nào hoặc thực hiện các phép tính phức tạp hoặc đưa ra quyết định kinh doanh, nên có ở đây. Tôi thường tổ chức logic kinh doanh của mình dưới dạng 'dịch vụ', lớp trình bày của tôi có thể yêu cầu thực hiện công việc được yêu cầu. Tất cả các mô hình miền của tôi tồn tại ở đây.

Cách tiếp cận của bạn

Đây là nơi tiếp cận của bạn phá vỡ một chút cho tôi. Bạn mô tả bộ điều khiển MVC của bạn là nơi bạn sẽ lấy dữ liệu từ kho lưu trữ và yêu cầu MPGCalculator thực hiện một số công việc, v.v. trong BLL.

Nói cách khác, tôi sẽ không đưa kho lưu trữ và MPGCalculator vào bộ điều khiển, điều đó mang lại cho bộ điều khiển quá nhiều trách nhiệm (nó đã xử lý tất cả các công cụ điều khiển mà tôi đã đề cập ở trên). Thay vào đó, tôi sẽ có một dịch vụ trong BLL xử lý tất cả điều đó và chuyển kết quả lại cho bộ điều khiển. Sau đó, bộ điều khiển có thể chuyển đổi kết quả thành mô hình chính xác và chuyển nó sang chế độ xem chính xác. Bộ điều khiển không có bất kỳ logic nghiệp vụ nào trong đó và những thứ duy nhất được đưa vào bộ điều khiển sẽ là các dịch vụ BLL thích hợp.

Làm theo cách này có nghĩa là logic kinh doanh của bạn (ví dụ: được cung cấp một bộ phương tiện, tính toán MPG và sắp xếp tốt nhất đến tồi tệ nhất ) không phụ thuộc vào mối quan tâm trình bày và tồn tại. Nó thường sẽ ở trong một thư viện không biết hoặc không quan tâm đến chiến lược lưu giữ dữ liệu cũng như chiến lược trình bày.


Xin chào Eric, trả lời xuất sắc - liên quan đến các kho lưu trữ, tôi cho rằng các lớp cụ thể sẽ sống trong lớp truy cập dữ liệu và 'ICarRep repository', v.v. trong lớp doanh nghiệp / dịch vụ? Sau đó, tôi có thể đưa dịch vụ vào bộ điều khiển của mình có thể chứa 1 hoặc nhiều kho lưu trữ tùy theo yêu cầu không?
Michael Harper

@MichaelHarper Vâng, đó có vẻ là một cách hoàn toàn tốt để đi về nó.
Eric King

1
Mặc dù xác thực là mối quan tâm của bộ điều khiển (các UI khác nhau xác thực khác nhau) Tôi muốn nói ủy quyền là logic nghiệp vụ và thuộc về lớp doanh nghiệp. Bạn có đồng ý không?
tom

1
@tom Vâng, bạn có một điểm tốt. Tôi đã nghĩ rằng ủy quyền đơn giản vì người dùng có quyền truy cập vào tuyến đường này , nhưng có thể có nhiều hơn thế. Phần "nhiều hơn thế nữa" thuộc về tầng lớp doanh nghiệp.
Eric King

1
@HunterNelson Nếu bạn ánh xạ vào chế độ xem, thì ánh xạ sẽ xảy ra ở chế độ xem, trong lớp trình bày. Nó sẽ không có ý nghĩa ở bất cứ nơi nào khác.
Eric King

0

Có vẻ như mọi thứ đều chính xác cho cấu trúc của bạn. Điều duy nhất mà tôi không chắc chắn là bạn đề cập rằng các mô hình trong MVC là "ViewModels" và bộ điều khiển của bạn nói chuyện với lớp miền. Tôi nghĩ điều này hợp lý nếu mẫu mặc định của bạn là sử dụng bộ điều khiển để truy cập vào lớp miền và sau đó sử dụng "ViewModels" của bạn dưới dạng các phần tổng hợp thông tin cụ thể của chế độ xem từ nhiều thực thể miền như ý nghĩa đối với chế độ xem cụ thể đó. Nếu đó là những gì bạn đang làm, thì bạn có khả năng ok.

Có một trường phái cho rằng bạn nên có một sự trừu tượng hóa hoàn toàn của lớp miền trong ứng dụng MVC của bạn nếu bạn sắp có. Cá nhân, ý nghĩ làm điều đó trong một ứng dụng doanh nghiệp khiến tôi đau đớn tinh thần nghiêm trọng.

Tôi thích sử dụng mẫu kho lưu trữ để quản lý quyền truy cập vào Lớp dữ liệu vì nó tăng cường khả năng kiểm tra và tính linh hoạt. Hai thứ có xu hướng tạo ra những thay đổi mạnh mẽ nhất là UI và cơ sở dữ liệu. Hãy tưởng tượng nếu một số thông tin mà bạn đang lấy trực tiếp ra khỏi cơ sở dữ liệu bị thay đổi để nó phải được truy xuất từ ​​một cuộc gọi dịch vụ thay vì một cuộc gọi cơ sở dữ liệu, hoặc một số thông tin được chuyển đến một cơ sở dữ liệu khác yêu cầu một .edmx khác tập tin. Các mẫu kho lưu trữ cung cấp trừu tượng để hỗ trợ này.


Cảm ơn câu trả lời William 😊 Tôi coi các đối tượng kinh doanh / logic và thực thể miền của mình là 'mô hình' mà bộ điều khiển sử dụng để xử lý các hành động của người dùng và chế độ xem như các mô hình cụ thể có thể chứa các nhóm mô hình, v.v.
Michael Harper
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.