Tại sao phải đưa logic kinh doanh vào mô hình? Điều gì xảy ra khi tôi có nhiều loại lưu trữ?


70

Tôi luôn nghĩ rằng logic nghiệp vụ phải nằm trong bộ điều khiển và bộ điều khiển, vì nó là phần 'giữa', giữ tĩnh và mô hình / khung nhìn phải được lật qua các giao diện. Bằng cách đó, bạn có thể thay đổi logic nghiệp vụ mà không ảnh hưởng đến bất kỳ điều gì khác, lập trình nhiều Mô hình (một cho mỗi cơ sở dữ liệu / loại lưu trữ) và hàng tá chế độ xem (ví dụ cho các nền tảng khác nhau).

Bây giờ tôi đọc trong câu hỏi này rằng bạn phải luôn đặt logic nghiệp vụ vào mô hình và bộ điều khiển được kết nối sâu sắc với khung nhìn.

Đối với tôi, điều đó thực sự không có ý nghĩa và ngụ ý rằng mỗi lần tôi muốn có phương tiện hỗ trợ cơ sở dữ liệu / loại lưu trữ khác tôi sẽ viết lại toàn bộ mô hình của mình bao gồm cả logic nghiệp vụ.

Và nếu tôi muốn một khung nhìn khác, tôi sẽ viết lại cả khung nhìn và bộ điều khiển.

Ai đó có thể giải thích tại sao đó là hoặc nếu tôi đã đi sai ở đâu đó?

Câu trả lời:


69

Câu trả lời của ElYusubov chủ yếu đóng đinh nó, logic miền nên đi vào mô hình và logic ứng dụng vào bộ điều khiển.

Hai làm rõ:

  • Thuật ngữ kinh doanh logic là khá vô dụng ở đây, bởi vì nó mơ hồ. Logic nghiệp vụ là một thuật ngữ chung cho tất cả logic mà người kinh doanh quan tâm, tách biệt nó khỏi các kỹ thuật đơn thuần như cách lưu trữ nội dung trong cơ sở dữ liệu hoặc cách hiển thị trên màn hình. Cả logic miền ("địa chỉ email hợp lệ trông giống như ...") và quy trình công việc / quy trình kinh doanh ("khi người dùng đăng ký, hãy hỏi địa chỉ email của anh ấy / cô ấy") được coi là logic kinh doanh, trước đây thuộc về logic mô hình và cái sau là logic ứng dụng đi trong bộ điều khiển.
  • MVC là một khuôn mẫu cho việc đưa nội dung trên một màn hình và cho phép người dùng tương tác với nó, nó không chỉ định lưu trữ ở tất cả . Hầu hết các khung MVC là các khung ngăn xếp đầy đủ vượt ra ngoài MVC đơn thuần và giúp bạn lưu trữ dữ liệu của bạn và vì dữ liệu nên được lưu trữ thường được tìm thấy trong mô hình, các khung này cung cấp cho bạn các cách lưu trữ mô hình thuận tiện- dữ liệu trong cơ sở dữ liệu, nhưng điều đó không liên quan gì đến MVC. Lý tưởng nhất là các mô hình nên không kiên trì và chuyển sang một loại lưu trữ khác hoàn toàn không ảnh hưởng đến mã mô hình. Kiến trúc đầy đủ có một lớp kiên trì để xử lý việc này.

4
Hầu hết các khung MVC đều trộn tất cả các công cụ lưu trữ / cơ sở dữ liệu vào mô hình để giúp dễ dàng lưu trữ các mô hình của bạn (thường bằng cách làm cho bạn mở rộng lớp mô hình khung). Đây có lẽ là nguồn gốc của sự nhầm lẫn. Về mặt kỹ thuật, mã mô hình bạn viết phải là mô hình thực tế (lớp miền), trong khi mã được cung cấp bởi khung nên xử lý lưu trữ (lớp bền vững). Ví dụ: một cái gì đó như User.find (...) (với Người dùng là một mô hình) hoạt động vì khung đã triển khai mẫu kho lưu trữ như một phần của Mô hình.
Chờ

3
View-Controller-Model-Storage là nguyên tắc chung (mặc dù mối quan hệ giữa M, V và C nên được hình dung như một hình tam giác). Khi khung của bạn trộn lưu trữ vào "mô hình" của chúng, nó hoạt động giống như thế này: Chế độ xem-Trình điều khiển- (Mô hình kế thừa lưu trữ từ khung).
Chờ

2
View-Controller-Model-Storage khá thô, vì nó không nên bằng phẳng. Ví dụ: khi bộ điều khiển thực hiện một cái gì đó như User.find (...) để lấy mô hình, nó sẽ hỏi lớp lưu trữ trực tiếp thay vì đi qua lớp miền.
Chờ

2
Trong các kiến ​​trúc với phân lớp cẩn thận hơn, nó sẽ giống như UserRep repository.find (). Theo "mô hình", ý tôi là lớp "mô hình" được cung cấp bởi khung công tác mà bạn kế thừa từ đó. Đối tượng người dùng được trả về bởi User.find () là mô hình của người dùng theo nghĩa ai đó đã mô hình hóa người dùng là gì, cách người dùng cư xử ...
Waquo

1
Logic kinh doanh @flipdoubt là bất kỳ logic nào nên được giữ nguyên nếu bạn chuyển từ mvc để nói ứng dụng uwp.
Andy

23

Bạn và các phần lớn của thế giới lập trình dường như hiểu sai vai trò của các phần MVC là gì. Nói tóm lại, chúng là:

Mô hình = logic miền

Xem = logic đầu ra

Bộ điều khiển = logic đầu vào

Điều này có nghĩa là mô hình chịu trách nhiệm cho toàn bộ logic nghiệp vụ: mọi thứ liên quan đến vẽ widget trên màn hình, lái máy in, xuất dữ liệu dưới dạng HTML, phân tích các yêu cầu HTTP, v.v. không thuộc mô hình.

Tuy nhiên, nhiều khung công tác hiện đại được gọi là "MVC" hoàn toàn không thực hiện MVC hoặc họ dán nhãn sai cho các bộ phận của chúng. Rất thường xuyên, cái được gọi là "mô hình" là lớp bền bỉ của mô hình, trong khi logic nghiệp vụ nằm trong cái mà họ gọi là "bộ điều khiển"; bộ điều khiển thực tế thường chỉ là một điểm vào trung tâm với bảng định tuyến và một chút mã trong các "bộ điều khiển" riêng lẻ để gửi đầu vào mà chúng nhận được đến các quy trình nghiệp vụ chính xác. Cái mà các khung công tác này gọi là "khung nhìn" thực sự là một chút của tất cả mọi thứ: một số logic trình bày (Chế độ xem), một chút xử lý đầu vào và xác thực (Bộ điều khiển) và một số logic kinh doanh (Mô hình) khác. Chia sẻ của sư tử về quan điểm thực tế thường được gọi là "mẫu".

Bạn cũng có thể muốn đọc về Kiến trúc nhiều tầng; Trong đó MVC là loại một chiều (luồng là Trình điều khiển -> Mô hình -> Chế độ xem), Đa tầng là một thứ hai chiều (Trình bày -> Logic -> Dữ liệu -> Logic -> Trình bày) và khá nhiều các khung giả vờ thực hiện MVC thực sự thực hiện Trình bày ba cấp, gắn nhãn lại để xem, Logic thành bộ điều khiển và dữ liệu cho mô hình.


2
Tôi tin rằng bạn mô tả sai Mô hình ("Mô hình = logic miền"), theo tôi, đó là một phương tiện cho dân số với dữ liệu, sau đó được hiển thị bằng cách sử dụng Chế độ xem, ở dạng thuần túy nhất của mẫu MVC. Chắc chắn trong các trường hợp sử dụng thực sự đơn giản, bạn có thể coi nó là "logic miền" nhưng tôi khẳng định rằng hầu hết các hệ thống có giá trị hiện tại sẽ nhanh chóng phát triển nhanh chóng. Tốt hơn là tách "logic miền" ra thành một lớp / lớp riêng biệt, ví dụ như một lớp dịch vụ.
A. Murray

@ A.Morrow: Tất nhiên Mô hình không phải là một khối mã nguyên khối và tách nó ra thành sự bền bỉ, cấu trúc dữ liệu và logic miền thường có nhiều ý nghĩa. Tuy nhiên, MVC nhóm ba mối quan tâm này với nhau trong Mô hình. Trong mọi trường hợp, khi bộ điều khiển và khung nhìn của bạn chứa logic miền, nó không còn là MVC thực.
tdammers

@tdammers, tôi thích sự gọn gàng trong câu trả lời của bạn và nó tập trung vào logic. Theo quan điểm của bạn, các mối quan tâm ứng dụng như sự kiên trì và xử lý giao dịch thuộc về đâu? Có vẻ như MVC phải là một từ viết tắt bốn chữ cái như MVCS trong đó S là dịch vụ.
flipdoubt

15

Để thực sự cô lập logic kinh doanh và làm cho nó tách biệt khỏi cơ sở hạ tầng lớp trình bày, nó cần được gói gọn bởi các dịch vụ ứng dụng. Kiến trúc MVC là một cách để thực hiện lớp trình bày và nó vẫn duy trì ở phạm vi đó, ủy thác tất cả logic nghiệp vụ cho các dịch vụ ứng dụng này. Hãy nghĩ về các mô hình xem như các bộ điều hợp giữa chế độ xem và dữ liệu cần được hiển thị trên và hoặc đọc. Bộ điều khiển làm trung gian cho sự tương tác giữa các mô hình xem, các khung nhìn và các dịch vụ ứng dụng lưu trữ logic nghiệp vụ.

Các dịch vụ ứng dụng triển khai các trường hợp sử dụng nghiệp vụ và được tách rời khỏi lớp trình bày, cho dù đó là MVC hay cái gì khác. Đổi lại, các dịch vụ ứng dụng có thể lưu trữ các tập lệnh giao dịch hoặc thiết kế theo hướng tên miền .

Để lưu trữ, dịch vụ ứng dụng có thể tham chiếu một kho lưu trữ hoặc bất kỳ sự trừu tượng hóa nào của một cơ chế lưu giữ lâu bền. Việc triển khai khác nhau có thể được hỗ trợ bằng cách trừu tượng hóa việc truy cập dữ liệu vào một giao diện. Thông thường, các tóm tắt này bị rò rỉ và chỉ có thể di chuyển một phần qua các triển khai và nó thường là một nỗ lực vô ích để đạt được tính di động đầy đủ.

CẬP NHẬT

Đề nghị của tôi dựa trên kiến trúc lục giác . Trong kiến ​​trúc hình lục giác, mô hình miền của bạn (logic nghiệp vụ) là cốt lõi. Lõi này được gói gọn bởi các dịch vụ ứng dụng hoạt động như một mặt tiền . Dịch vụ ứng dụng là các lớp đơn giản có các phương thức tương ứng với các trường hợp sử dụng trong miền của bạn. Để thảo luận chuyên sâu về các dịch vụ ứng dụng, hãy xem Dịch vụ trong Thiết kế hướng tên miền . Mẫu mã chứa một PurchaseOrderServicedịch vụ ứng dụng cho miền mua hàng. (Lưu ý rằng một dịch vụ ứng dụng không ngụ ý việc sử dụng thiết kế hướng tên miền.)

Trong kiến ​​trúc hình lục giác, lớp trình bày MVC là một bộ chuyển đổi giữa mô hình miền của bạn (logic nghiệp vụ) và GUI. Mô hình miền không biết về lớp trình bày, nhưng lớp trình bày nhận biết về mô hình miền.

Giải pháp này chắc chắn có các bộ phận chuyển động hơn là một giải pháp đặt logic kinh doanh trong bộ điều khiển và bạn nên cân nhắc những hạn chế và lợi ích. Lý do tôi đề nghị là vì tôi thích giữ logic kinh doanh tách rời khỏi lớp trình bày để chống lại sự phức tạp. Điều này trở nên quan trọng hơn khi ứng dụng phát triển.


Âm thanh giống như bạn đang mô tả một tên khốn của MVC và MVVM có cả bộ điều khiển và mô hình xem. Ngoài ra, tôi nghĩ kiến ​​trúc mà bạn mô tả có thể hơi nặng nề đối với nhu cầu của OP.
Chờ

Thành thật mà nói, tôi thích câu trả lời của Waquo hơn. Chủ yếu là vì tôi không hiểu ý của bạn với 'dịch vụ ứng dụng'. Bạn có thể giải thích thuật ngữ đó? GoogleFU của tôi không hoạt động ở đây vì nó có vẻ như.
Steffen Winkler

1
@Waquo Tôi đồng ý rằng kiến ​​trúc được đề xuất có thể là quá mức cần thiết, tuy nhiên nó nên được xem xét. Tôi đã không đề cập đến MVVM, đơn giản là một cách khác để triển khai lớp trình bày. Các dịch vụ ứng dụng áp dụng bất kể bạn sử dụng MVC hay MVVM và không có gì tôi đề xuất cho thấy bất kỳ sự kết hợp nào của cả hai.
eulerfx

1

Phụ thuộc vào những gì bạn có nghĩa là logic kinh doanh. Bất kỳ "logic" nào có ý nghĩa đối với nội dung của mô hình nên có trong mô hình. Trong câu hỏi được liên kết, câu trả lời được bình chọn cao nhất dường như định nghĩa "logic kinh doanh" là bất cứ điều gì liên quan đến dữ liệu; điều này có ý nghĩa từ quan điểm rằng dữ liệu của một doanh nghiệp là kinh doanh của nó!

Tôi đã từng thấy một ví dụ của người tạo ra Rails (tôi nghĩ), người đang diễn ra về chính xác điều này - không đưa "logic kinh doanh" vào mô hình. Ví dụ của anh ta là một lớp trình điều khiển và phương thức đăng ký và đăng nhập ứng dụng - mật khẩu được cung cấp trong bản rõ đã được mã hóa trước khi đưa vào hoặc truy vấn đối với mô hình (cơ sở dữ liệu.)

Tôi không thể nghĩ ra một ví dụ tốt hơn về thứ gì đó không phải là bộ điều khiển logic và thuộc về trực tiếp trong mô hình.

Mô hình này có thể là một giao diện cho vô số kho lưu trữ dữ liệu, làm giảm bớt những lo ngại về tính di động. Ở đây, người ta có thể tìm thấy sự nhầm lẫn về thời tiết hoặc không phải giao diện mô hình thực sự là "bộ điều khiển".

Nói chung, bộ điều khiển liên kết mô hình và chế độ xem (là thịt và khoai tây của ứng dụng.) Trong quá trình phát triển Ca cao, có thể đơn giản đến điểm mà bộ điều khiển được xử lý thông qua GUI XCode (đối tượng và các ràng buộc của bộ điều khiển.)

Phần "Mẫu thiết kế" của GoF trên MVC, được trích dẫn một cách lỏng lẻo:

Bộ ba MVC của các lớp được sử dụng để xây dựng giao diện người dùng trong Smalltalk-80. Model là đối tượng ứng dụng, View là phần trình bày màn hình của nó và Trình điều khiển xác định cách UI phản ứng với đầu vào của người dùng. MVC tách các khung nhìn và mô hình bằng cách thiết lập giao thức đăng ký / thông báo giữa chúng. Sơ đồ sau đây cho thấy một mô hình và ba khung nhìn. Chúng tôi đã để lại các bộ điều khiển cho đơn giản.

MVC là tất cả về UI. Trọng tâm là mô hình và khung nhìn - xác định và hiển thị dữ liệu. Lưu ý "giao thức đăng ký / thông báo" - đây là nơi bộ điều khiển của bạn xuất hiện. Bạn có thể xây dựng tất cả các chế độ xem bạn muốn; miễn là chúng tuân thủ giao thức, bạn sẽ không bao giờ phải chạm vào mô hình hoặc bộ điều khiển.

Nếu bạn đang nói về phát triển web một cách cụ thể, IMHO nhiều khung web phổ biến sẽ nhanh và lỏng với thuật ngữ MVC và các định nghĩa thành phần của nó.


Tôi là nhà phát triển C # / Java (chỉ có một vài dự án ở đó). Có vẻ như tôi đã hiểu nhầm những gì người mẫu làm. Việc đưa 'logic kinh doanh' vào bộ điều khiển thực sự chỉ là một hậu quả (sự suy nghĩ của tôi đã đi 'được rồi, tôi là mô hình cho dữ liệu (đọc: kết nối / lưu trữ cơ sở dữ liệu), vì vậy logic kinh doanh của tôi cần phải có trong bộ điều khiển vì Tôi phải áp dụng nó trước khi lưu trữ dữ liệu trong cơ sở dữ liệu '. Chỉ cần chuyển mọi thứ xuống một cấp từ bộ điều khiển. Thực tế, nó giải quyết được một vấn đề tôi hiện đang gặp phải (hỗ trợ MySQL và MSSQL trong một chương trình)
Steffen Winkler

0

Tại sao bạn không giới thiệu một lớp dịch vụ?

Sau đó, bộ điều khiển của bạn sẽ gọn gàng và dễ đọc hơn, sau đó tất cả các chức năng của bộ điều khiển sẽ là các hành động thuần túy.

Bạn có thể phân tách logic nghiệp vụ nhiều như bạn cần trong lớp dịch vụ. Khả năng sử dụng lại mã là tốt hơn và không có tác động đến các mô hình và kho lưu trữ.

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.