Trong MVC, nó được coi là thực hành tốt để có các chức năng riêng tư, không hành động, trong một lớp trình điều khiển?


10

Đôi khi các hàm hành động trong lớp trình điều khiển có thể trở nên to lớn và khó chịu, với nhiều dòng mã chỉ đơn giản là kiểm soát luồng dữ liệu từ Mô hình đến Chế độ xem. Tại một số điểm, các hàm lớn này hoàn toàn mất dấu các nguyên tắc cơ bản của mã tốt, tức là chỉ làm một việc, nhỏ, dễ đọc và dễ quản lý, v.v.

Nó có được coi là thực hành tốt để chia các hàm hành động khổng lồ này thành các hàm riêng nhỏ hơn trong lớp trình điều khiển hay không nếu nhu cầu tối ưu hóa như vậy có nghĩa là chúng ta nên thêm chúng vào mô hình?

Tôi sẽ bỏ phiếu cho việc có các chức năng nhỏ hơn là riêng tư trong bộ điều khiển để chúng có liên quan đến hành động, nhưng tôi đã nghe thấy các đối số rằng bộ điều khiển tốt nhất nên đơn giản trong khi mô hình có thể trở nên to lớn và vón cục; và chỉ tự hỏi cái nào sẽ là phương pháp được ưa thích nhất.

Câu trả lời:


16

Có thể không phải là sự tương tự tốt nhất, nhưng, hãy nghĩ về bộ điều khiển giống như cách bạn nghĩ về mạng nhện. Công việc duy nhất của nó là bắt ruồi (yêu cầu) để nhện (lớp bên dưới) tiêu hóa. Web có thể bắt và giữ ruồi nhỏ hơn hoặc lớn hơn (mô hình). Vai trò web của nhện không phải là để tiêu hóa con mồi, mặc dù nó có thể được sử dụng cho mục đích này. Mạng càng mỏng và sạch hơn, nhện càng dễ kiếm sống.

Bạn có thể áp dụng logic tương tự cho ứng dụng MVC của mình. Các hàm lớn và khó chịu mà bạn mô tả rất có thể là hành vi của mô hình và chúng phải thuộc về mô hình (lưu ý rằng mô hình không chỉ là đối tượng được hiển thị trong chế độ xem). Nếu hành vi của mô hình thay đổi thì đó là mô hình nên được thay đổi và không phải là bộ điều khiển xử lý nó.

Ngoài ra, giữ chúng như các phương thức riêng tư trong bộ điều khiển sẽ chỉ làm lộn xộn nó và làm cho nó khó bảo trì. Nó cũng mở đường cho một thói quen xấu, vì những người khác có liên quan đến phát triển sẽ bị cám dỗ làm điều tương tự, vì họ đã thấy nó được thực hiện trước đó trong dự án.


+1 cho sự tương tự sáng tạo. :) Bạn làm cho một điểm thú vị. Đặc biệt là về sự hình thành thói quen xấu. Cảm ơn bạn.
David 'gừng hói'

8

Câu trả lời tốt nhất tôi có thể đưa ra là trích dẫn từ cuốn sách tuyệt vời của Robert Martin, "Clean Code" mà tôi đặc biệt giới thiệu cho bất kỳ ai quan tâm đến chủ đề này:

Nguyên tắc đầu tiên của chức năng là chúng phải nhỏ. Quy tắc thứ hai là chúng nên nhỏ hơn thế.

Không thể nói nó tốt hơn. Một trích dẫn tuyệt vời khác từ cùng một cuốn sách được áp dụng:

Chức năng nên làm một việc. Họ nên làm điều đó tốt. Họ chỉ nên làm điều đó.

Khi chia mã của bạn thành nhiều hàm hơn, bạn buộc phải đặt cho các hàm đó những tên có ý nghĩa có thể cải thiện đáng kể khả năng đọc mã của bạn. Không cần phải nói, tất cả các hàm không dành cho sử dụng bên ngoài lớp, nên ở chế độ riêng tư, vì vậy bạn có thể dễ dàng sử dụng lại mã của mình thông qua kế thừa.

Nếu bộ điều khiển của bạn bây giờ có quá nhiều chức năng, đó là một dấu hiệu cho thấy nó có thể làm quá nhiều. Sau đó, bạn có thể chia nó thành nhiều phần độc lập hoặc cố gắng di chuyển một số chức năng sang các mô hình như được đề cập trong câu trả lời khác. Ngoài ra nếu bạn theo hương vị MVC phi cổ điển, trong đó Chế độ xem được phép có một số logic, bạn có thể đặt một số chức năng của mình ở đó bất cứ khi nào nó phù hợp.


1
Tôi không nghĩ rằng việc đưa logic kinh doanh vào các khung nhìn là "MVC phi cổ điển", đó chỉ là "MVC xấu". Rõ ràng bạn cần các cấu trúc kiểm soát cơ bản trong các khung nhìn, nhưng chúng phải được liên kết với các mối quan tâm của người dùng / UI, chứ không phải các mối quan tâm về miền / doanh nghiệp. Một chức năng thực tế trong một khung nhìn là khá kinh khủng.
Aaronaught

1
@Aaronaught Tôi mơ hồ với "một số logic", những gì tôi có trong đầu là ví dụ thư viện Backbone.js, nơi bạn đặt các sự kiện và chức năng của người dùng để xử lý chúng theo quan điểm của bạn. Trong MVC cổ điển, đây là công việc của bộ điều khiển. Tuy nhiên, điều này có thể không thực tế vì bạn sẽ cần điều chỉnh cả Chế độ xem và Trình điều khiển mỗi khi UI của bạn thay đổi. Bằng cách đặt các hàm xử lý UI của bạn trong Chế độ xem, bạn chỉ cần điều chỉnh Chế độ xem. Đó chỉ là quan điểm chủ quan của tôi - tôi có thiếu điều gì không?
Dmitri Zaitsev

1
Chỉ vì một cái gì đó được phân phối ở phía khách hàng không có nghĩa là nó là một phần của khung nhìn. Các ràng buộc dữ liệu trong các khung nhìn, chắc chắn, nhưng Backbone tự nó là một khung công tác MV * (loại MVC, loại MVP, không hoàn toàn) và các kịch bản phía máy khách của bạn nên được tổ chức phù hợp; nếu không, bạn chỉ đang hack.
Aaronaught

0

Trong MVC tôi cố gắng và đảm bảo rằng bộ điều khiển của tôi càng "mỏng" càng tốt và các mô hình của tôi càng ngu ngốc càng tốt.

Các hàm trợ giúp logic và trợ giúp cần thiết được đưa vào các lớp trợ giúp độc lập riêng biệt. Nó cũng giúp cho việc kiểm tra của tôi dễ dàng hơn rất nhiều (bạn đang kiểm tra .. phải không ??: D) Kiểm soát kiểm tra rất khó khăn, bất cứ khi nào bạn thử và tạo một phiên bản của bộ điều khiển để kiểm tra bạn phải suy nghĩ về Ngữ cảnh HTTP và giả mạo http cái này và cái kia, và nó là một nỗi đau, nhưng đó là một nỗi đau về mục đích. Bạn cần tất cả những thứ đó vì bộ điều khiển được liên kết chặt chẽ với HTTP và web. Đó là điểm vào ứng dụng web của bạn.

Các hàm logic và trợ giúp không liên quan gì đến web. Họ hoàn toàn không tin tưởng vào môi trường (hoặc họ nên như vậy). Điều đó một mình sẽ nói với bạn rằng họ không thuộc về nhau ở cùng một nơi. Ngoài ra, nếu bạn liên kết chặt chẽ tất cả logic ứng dụng của mình với web hoặc triển khai web cụ thể, bạn không bao giờ có thể mang theo bên mình.

Chúng tôi đã phát triển trang web MVC của chúng tôi với tất cả các thực thể cơ sở dữ liệu của chúng tôi (không phải mô hình mvc, thực thể db thực tế của chúng tôi), lưu trữ của chúng tôi, các lớp trợ giúp và logic của chúng tôi trong riêng biệt dll. Chúng tôi chỉ có mỗi một trang web, nhưng dù sao chúng tôi cũng đã làm như vậy.

Một vài tháng trước, chúng tôi đã được yêu cầu tạo ra một vài ứng dụng máy tính để bàn có liên quan đến một vài hệ thống bên lề của chúng tôi. Điều này được thực hiện dễ dàng vì tất cả các mã được thử nghiệm của chúng tôi có thể dễ dàng được sử dụng lại. Nếu chúng tôi đưa mã của chúng tôi vào dự án web của chúng tôi hoặc đưa vào bộ điều khiển của chúng tôi, chúng tôi sẽ không bao giờ có thể làm điều này.


2
Mô hình trong MVC là lớp duy nhất không bị câm. Nếu thông minh không có trong mô hình và chúng không có trong bộ điều khiển, thì chúng ở đâu ... trong chế độ xem? Bộ điều khiển cũng không khó để kiểm tra; khả năng sử dụng DI và giả / giả để tạo điều kiện kiểm tra đơn vị là một trong những điểm thu hút của MVC so với các khung công tác khác. Hầu hết các bài kiểm tra điều khiển của tôi là dưới 5 dòng.
Aaronaught

tôi sẽ sử dụng một lớp "người trợ giúp" với logic thay vì thẩm thấu một mô hình bằng logic. loại logic nào bạn sẽ đặt trong một mô hình? Nó có biết làm thế nào để tự tải và tự lưu? Tôi đồng ý giả mạo / khai thác là dễ dàng, nhưng nó không phải là một lý do để bắt đầu vỗ béo bộ điều khiển của bạn.
phi công

Tôi có cảm giác rằng câu trả lời này có nghĩa tốt nhưng nó được diễn đạt không chính xác .. hoặc, có lẽ là thuật ngữ khác nhau.
Simon Whitehead

3
Các lớp "Người trợ giúp" không phải là một yếu tố kiến ​​trúc. Chúng là một phần của M, V hoặc C. Nếu bạn không chắc chắn về điều đó, thì những người trợ giúp đó thiếu sự gắn kết . Từ "người trợ giúp" cũng được xếp ngay trên đó với "xử lý", "làm", "thực hiện" và Trình quản lý đáng sợ .
Aaronaught

@SimonWhitehead: Hầu hết các câu trả lời đều có nghĩa tốt nhưng nhiều câu trả lời không đúng. Thật không may, điều này là, hoặc là thúc đẩy sự hiểu lầm về ý nghĩa của "Mô hình" hoặc khuyến nghị đưa logic kinh doanh quan trọng ra bên ngoài nó. Tôi đã có niềm vui mơ hồ là duy trì các trang web MVC với hàng triệu "người trợ giúp" - chúng thật đáng sợ.
Aaronaught

-2

Bên cạnh Dmitri Zaitsev và spaceman câu trả lời tuyệt vời tôi không biết nếu những điều sau đây cũng hợp lệ đối với PHP: Bạn nên cố gắng tránh các phương thức riêng tư do thiếu khả năng kiểm tra tự động.

Có, bạn cũng có thể sử dụng siêu lập trình hoặc tiêm phụ thuộc để kiểm tra các phương thức riêng tư nhưng bạn không nên làm điều đó vì nó có tác động rất lớn đến khả năng đọc mã của bạn.

Luôn nhớ nguyên tắc KISS: Giữ cho nó đơn giản, ngu ngốc.


5
Đó không phải là lý do chính đáng để tránh các phương thức riêng tư và cũng không liên quan gì đến kiến ​​trúc MVC. Bạn không thử kiểm tra các phương thức riêng tư, chúng nên được kiểm tra bằng các phương pháp công khai . Nếu bạn không thể bao quát chúng, thì đó là dấu hiệu cho thấy lớp học của bạn quá phức tạp và cần được tái cấu trúc; điều đó không có nghĩa là bạn không nên có phương pháp riêng tư hoặc (tôi thực sự hy vọng đây không phải là điều bạn thực sự muốn nói) rằng chúng nên được công khai thay thế.
Aaronaught
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.