2012-02-28 37 views
5

Tôi đang xây dựng một dự án hiện có 3 cụm:Kiến trúc cho dự án web MVC/sử dụng các loại khác nhau của mô hình

  • UI
  • Core (Dịch vụ & Models, Utilities)
  • Repositories (Linq2SQL)

Dependencies là

  • Giao diện người dùng -> Lõi
  • Lõi -> Kho lưu trữ.

Tôi muốn dịch vụ và mô hình là trong hội đồng của mình và kết thúc với một cái gì đó được xây dựng xung quanh mô hình tức là:

  • UI -> Models, Dịch vụ
  • Dịch Vụ -> Models , Repositories
  • Repositories -> Models
  • Models

Th Hệ thống điện tử tôi đang xây dựng về cơ bản là một CMS của trang web vì vậy tôi sẽ có một mô hình cho một trang web (PageModel) có một bộ sưu tập các trang web con. PageModel có thể gọi các phương thức trong một dịch vụ (PageService) để cư trú các trang con của nó nhưng trong thiết kế mới không thể xảy ra vì lắp ráp Mô hình nhất thiết không biết gì về hội đồng dịch vụ.

Tôi đã xem xét một số ý tưởng trong Kiến trúc Onion (cụ thể là tiêm phụ thuộc) để giải quyết vấn đề này, nhưng có vẻ như một giải pháp rõ ràng hơn/rõ ràng hơn có thể có sẵn.

Tôi có cần giới thiệu một lớp Mô hình khác không? Xem mô hình? Tôi nghĩ những gì tôi gọi là Mô hình là Mô hình miền ... Tôi có thể rất sai! Dịch vụ sau đó sẽ là Dịch vụ miền?

Vì vậy, giải pháp của tôi sẽ là:

  • UI -> Dịch vụ, ViewModels, Models
  • ViewModels -> Dịch vụ, Models
  • Dịch Vụ -> Repositories, Models
  • Repositories -> Models
  • Mô hình

Trong ví dụ này tôi tưởng tượng m y PageViewModel sẽ mở rộng PageModel và sử dụng PageService để tìm nạp các trang con của nó ..

Bất kỳ đề xuất nào được đánh giá cao. Ngoài ra bất kỳ con trỏ trên những gì các lớp mô hình thường được gọi là? Tôi có đang nói về Mô hình DTO hơn là Mô hình miền ở đây không? Và Mô hình Tên miền thay vì Xem Mô hình? Nó có vẻ như những gì tôi đang đề xuất để sử dụng các mô hình xem cho không thực sự là công việc của một mô hình xem ..

Cảm ơn

EDIT:

Cái gì tôi đã không được đề cập ban đầu là Models miền của tôi không phải là dịch cơ bản của các tổ chức cơ sở dữ liệu duy nhất như bạn có xu hướng nhìn thấy trong hầu hết các hướng dẫn. Một mô hình miền có thể chứa các trường dữ liệu đến từ một số bảng cơ sở dữ liệu có liên quan.

Vì vậy, nó sẽ có giá trị có một tập hợp các mô hình hoàn toàn để đóng gói dữ liệu trong tên miền - mà không có bất kỳ phương pháp/thuộc tính tìm nạp các đối tượng liên quan hoặc lưu đối tượng trở lại DB vv? - Đối tượng chuyển dữ liệu.

Từ việc xem xét một vài sơ đồ nguệch ngoạc, điều này có nghĩa là có một nhóm người lập bản đồ trong lớp miền (có vẻ như sai ..) để dịch mô hình DTO sang Mô hình miền và ngược lại. Dự án sẽ được xây dựng xung quanh các mô hình DTO hơn là các mô hình miền nhưng được đưa vào những gì được đóng gói bởi DTO, tôi không thấy đó là một vấn đề.

Đối với bất cứ ai quan tâm, cấu trúc phụ thuộc đề xuất sẽ là như vậy:

  • UI -> Dịch vụ, Domain Models
  • Dịch Vụ -> Repositories, miền Models, DTO Models
  • miền Models - > Repositories, DTO Models
  • Mappers -> Mô hình domain, DTO Models
  • Repositories -> Models DTO
  • DT Mô hình O (không phụ thuộc)

Đó là một chút lộn xộn! Và tất cả chỉ vì tôi muốn PageModel của tôi có thể tìm nạp các PageModels con riêng của mình .. Có vẻ như việc đi tiêm phụ thuộc có thể không phải là một kế hoạch xấu.

Nhờ những người đã trả lời. Bạn đã cho tôi tải để suy nghĩ về.

Trả lời

2

Bạn có thể thực hiện điều này tốt với kiến ​​trúc hành tây. tôi sẽ có ví dụ: UI, Domain, truy cập dữ liệu, Dịch vụ

UI Dịch vụ truy cập dữ liệu miền (chứa mô hình xem cũng)

UI có thể truy cập bất kỳ một. Dịch vụ, chỉ truy cập và miền dữ liệu. Truy cập dữ liệu - chỉ tên miền.

Giao diện kho lưu trữ của tôi nằm trong dự án miền và chúng được triển khai trong dự án truy cập dữ liệu. Tôi cũng giữ các giao diện khác trong dự án miền (IContext, IUnitOfWork, v.v.) vì vậy tôi có một vị trí trung tâm và không phát tán quá nhiều giao diện giữa các dự án.

DTO sẽ chỉ được sử dụng để chuyển giữa các lớp, nếu bạn cho là phù hợp. Không có lý do gì đối với tôi, bạn không thể chuyển mô hình miền từ lớp dữ liệu lên, một số chọn chỉ sử dụng DTO ở đây.Tôi sẽ thực hiện ánh xạ trong lớp giao diện người dùng (bộ điều khiển MVC cũ) cho ViewModel vì tôi có thể sử dụng AoP để làm điều đó cho tôi ([Thuộc tính [Tự động()]

Chỉ cần nhớ rằng mô hình của bạn không được chứa bất kỳ logic bền bỉ nào cả.

+0

Cảm ơn Adam. Đặt các giao diện kho lưu trữ trong Miền có vẻ là một cách gọn gàng để giữ mọi thứ tập trung xung quanh miền. Trên điểm kiên trì, Mô hình miền của tôi có các phương thức thuận tiện cho Save(), chỉ cần gọi phương thức Save() trong kho lưu trữ có liên quan. Bạn có xem đó là logic bền bỉ và do đó thực hành không tốt? – Giles

+0

ya, họ không biết gì về nó. Chuyển thực thể đến kho lưu trữ của bạn và để nó là nơi duy nhất để xử lý mọi thứ. điều này sau đó thích hợp với một đơn vị mẫu công việc, vì các kho lưu trữ có thể được tái cấu trúc để bây giờ thực sự lưu nó vào một bộ sưu tập và đơn vị thực hiện công việc lưu bộ sưu tập đó vào db trong một giao dịch. Các dịch vụ của bạn, thay vì gọi Save() trên các mô hình, thay vào đó chỉ cần biết để gọi thực hiện kho lưu trữ, cần được đưa vào bộ điều khiển hoặc kho lưu trữ của bạn. Điều này cho vay chính nó độc đáo để thử nghiệm/mocking/etc. –

2

Tôi nghĩ rằng nó khá điển hình của bất kỳ ứng dụng "thế giới thực" nào để lưu trữ dữ liệu khác với được hiển thị trên màn hình. Tôi nghĩ rằng bạn đang đi đúng hướng, với 2 mô hình riêng biệt. Tôi thường kết thúc việc gọi cho họ:

  • ViewModels - ánh xạ tới những gì được hiển thị trên màn hình, những gì người xem muốn.
  • DataModels - ánh xạ tới DB, lớp kiên trì (ORM) muốn.

Đôi khi DataModels được gọi là Entities đặc biệt là khi nói về Khung thực thể làm lớp truy cập dữ liệu hoặc Data Transfer Objects (DTO).

Thông thường, có một số bộ "dịch giả" để ánh xạ từ chế độ xem sang mô hình dữ liệu quá hoặc đôi khi có thể sử dụng AutoMapper.

Tất nhiên nếu những gì bạn đang hiển thị đủ gần với cấu trúc dữ liệu của bạn, sẽ không có hại nào chuyển tất cả các mô hình/mô hình dữ liệu đến Chế độ xem, nhưng tôi cũng muốn tách riêng chúng.

+0

Cảm ơn. Tôi bắt đầu tự hỏi về các mô hình DTO. Mô hình của tôi không nhất thiết là ánh xạ đơn giản từ các bảng cơ sở dữ liệu đơn lẻ. Tôi có thể phải trả lời bài của tôi để giải thích rằng mặc dù đúng .. – Giles

2

Tôi đã xem xét một số ý tưởng trong Kiến trúc Onion (cụ thể là tiêm phụ thuộc) để giải quyết vấn đề này, nhưng có vẻ như một giải pháp rõ ràng hơn.

Khi bạn sử dụng Dependency Injection đúng cách, đây thực sự là giải pháp rất thanh lịch/hiển nhiên.

tôi muốn đề nghị một cấu trúc phụ thuộc như thế này:

  • UI
    • Controller -> Dịch vụ, mô hình, ViewModels
    • Views -> ViewModels
    • ViewModels (không phụ thuộc)
  • Dịch vụ -> Kho lưu trữ, Mô hình
  • Repositories -> Models
  • Models

này là khá gần với những gì bạn đã có trước đó, nhưng ViewModels của bạn là một phần của dự án giao diện người dùng của bạn và không có phụ thuộc gì cả. Họ chỉ nên là các lớp đơn giản đại diện cho những gì bạn muốn hiển thị cho người dùng.

Đó là công việc của bộ điều khiển để:

  • Gọi các dịch vụ để có được những mô hình,
  • Dịch các mô hình thành ViewModels và
  • Gọi View đang

xem không nên yêu cầu bất kỳ thông tin nào không được cung cấp bởi ViewModels.

+0

Cảm ơn. Tôi nghĩ Dependency Injection bắt đầu giống như con đường để đi. Dự án đã khá phức tạp mặc dù (theo tiêu chuẩn của tôi ..) và thực hiện DI có thể là một thách thức khá .. – Giles

+0

@Giles: DI có xu hướng làm cho bạn làm theo các mẫu thiết kế tốt. Vì bạn đã không sử dụng tất cả cùng, có thể có một số cơn đau đang cố gắng làm cho mã của bạn tuân theo các mẫu mà lẽ ra nó đã được sử dụng tất cả cùng. Nhưng nếu bạn làm đúng, DI thực sự sẽ giúp bạn đơn giản hóa mọi thứ một chút. May mắn nhất. – StriplingWarrior

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