Có bất kỳ nghiên cứu khoa học nghiêm ngặt về các nguyên tắc phong cách mã hóa? [đóng cửa]


25

Là một nguyên tắc phong cách mã hóa - ví dụ như nguyên tắc thoát đơn - thực sự là một điều tốt? Luôn luôn, hoặc chỉ đôi khi? Nó thực sự tạo ra bao nhiêu sự khác biệt?

Dù ý kiến ​​của bạn là gì, đây rõ ràng là những câu hỏi chủ quan. Hoặc là họ?

Có ai đã cố gắng thực hiện một nghiên cứu khoa học, nghiêm ngặt về các nguyên tắc phong cách mã hóa chưa?

Tôi không thể tưởng tượng làm thế nào bất cứ ai sẽ thực hiện một nghiên cứu mù đôi về khả năng đọc, nhưng có thể không biết gì về hai người - sử dụng những sinh viên không biết về nguyên tắc được nghiên cứu như các môn học và những người không lập trình để quản lý nghiên cứu.


5
Bạn có thể được xen kẽ trong việc đọc mã hoàn thành. Mọi thứ đều không thể tin được, nhưng rất nhiều, và bạn sẽ tìm thấy một tổng quan tốt với dữ liệu thô hoặc nguồn trong cuốn sách này.
deadalnix

Nó cũng phụ thuộc nhiều vào ngôn ngữ, một số nguyên tắc áp dụng cho các ngôn ngữ cụ thể chứ không phải các ngôn ngữ khác. Ví dụ: single-exit principlekhông thực sự áp dụng cho C ++ vì RAII
Martin York


@Loki - Tôi đã phải suy nghĩ về điều đó, và tôi không chắc là mình đồng ý. Đúng là RAII được thiết kế phần lớn để đối phó với các ngoại lệ, đó là các điểm thoát thay thế, nhưng (ít nhất là đối với một số người) họ tính là các điểm thoát thay thế thay thế - không thực sự dựa trên nguyên tắc thoát đơn theo cách đó break, gotohoặc returnlàm Lối thoát đơn IOW không phải là tuyệt đối trong C ++, nhưng đó gần như là quan điểm của tôi về C và hầu hết các ngôn ngữ khác. Nhưng nó vẫn có liên quan theo nghĩa không nghiêm ngặt.
Steve314

1
@ Steve314, bài viết ít nhất có liên quan xa - nó phác thảo một thiết kế cho một phương pháp của một thí nghiệm như vậy, điều này khá quan trọng do thiếu rõ ràng bằng chứng thực nghiệm được ghi lại đúng trong lĩnh vực này.
SK-logic

Câu trả lời:


11

Tôi đang lặp lại bình luận của deadalnix: đọc Code Complete 2 . Tác giả (Steve McConnell) thảo luận về phong cách mã hóa theo chiều sâu và thường xuyên tham khảo các bài báo và dữ liệu.


Tổng quan cơ bản và được trình bày tốt về phát triển phần mềm chuyên nghiệp, hy vọng một ngày nào đó tôi sẽ tìm thấy một cái tương tự để đảm bảo chất lượng. Các chương về Lập trình phòng thủ và Lập trình mã giả đặc biệt hữu ích với tôi. Chương về Thực tiễn Phát triển Hợp tác dường như hấp dẫn nhất trong tất cả những gì tôi đã đọc về những vấn đề này cho đến nay.
gnat

Tôi đã không đọc cuốn sách này, và có lẽ tôi nên, nhưng - dựa trên những nhận xét trong câu trả lời của gnats - liệu những bài báo được tham khảo có thực sự khoa học và khách quan không? Nếu câu trả lời là "càng nhiều càng tốt", những thỏa hiệp nào là cần thiết? Như tôi đã đề xuất trong câu hỏi, có cần thiết phải thay thế mù đôi bằng một số tiêu chuẩn yếu hơn không?
Steve314

@ Steve314: Tôi không biết, tôi đã không kiểm tra các nguồn! Nhưng bạn không phải lúc nào cũng cần sự nghiêm ngặt về khoa học để thiết lập thực hành tốt nhất. Một cuộc thảo luận về những ưu và nhược điểm đôi khi là đủ.
M. Dudley

@emddudley - Hoàn toàn đúng, nhưng không thực sự câu hỏi này là về cái gì.
Steve314

@ Steve314: Code Complete sẽ là điểm khởi đầu tuyệt vời cho bạn và tôi tin tưởng rằng một số tài liệu tham khảo của nó đề cập đến vấn đề phân tích khoa học về phong cách mã hóa.
M. Dudley

12

Tôi rất nghi ngờ về khả năng của một nghiên cứu về chủ đề mang lại kết quả khách quan và tôi sẽ vẫn hoài nghi cho đến khi tôi được hiển thị một số nghiên cứu thuyết phục.

Các lập trình viên đã dành nhiều năm để đọc và viết mã theo phong cách mã hóa nhất định rõ ràng sẽ thấy nó dễ đọc hơn một số phong cách mã hóa hoàn hảo mà họ sẽ thấy lần đầu tiên trong đời.

Nó hoàn toàn giống với cách bố trí gõ QWERTY phổ biến nhất - thật dễ dàng để chứng minh rằng nó khá tối ưu về mặt công thái học (bạn có nghĩ rằng tất cả các ký tự của từ TYPEWRITER đều được đặt ở hàng trên cùng với sự tiện lợi hàng ngày của chúng tôi không?) .

Nhưng các lựa chọn thay thế được cải thiện như Dvorak hoặc Colemak chưa bao giờ bắt kịp và khó có thể xảy ra. Và do đó mọi người không làm việc hiệu quả hơn với họ - thực tế. Ngay cả khi họ vượt trội trong một số ý nghĩa trừu tượng.

Ngoài ra, nó sẽ rất khó để tìm thấy các đối tượng không có tiếp xúc trước khi lập trình (vì điều này sẽ làm ô nhiễm các kết quả nghiên cứu của chúng tôi), NHƯNG một năng khiếu cho lập trình, và có ý muốn tham gia vào một nghiên cứu trong một thời gian đủ lâu để hiển thị cả ngắn lợi ích thời gian và lợi ích lâu dài để chúng có thể được cân đối với nhau ... (Tôi không biết liệu chúng có loại trừ lẫn nhau hay không, nhưng các nhà nghiên cứu không thể đơn giản cho rằng chúng không bao giờ tồn tại).


1
Thật tuyệt, tôi chưa bao giờ nghe nói về Colemak trước đây
CaffGeek

1
@Chad thậm chí còn ít được biết đến là Carpal X, mà tôi đã chơi đùa trong một thời gian. Tôi thấy nó đẹp hơn Colemak (tôi đạt 90-100 wpm với carpalx). Ngay cả khi bạn không có ý định chuyển sang bất kỳ bố cục kỳ lạ nào, trang web carpalx vẫn đọc một cách cực kỳ thú vị về việc đánh giá và tối ưu hóa bố cục bàn phím và sử dụng thuật toán di truyền cho loại vấn đề này. Xem mkweb.bcgsc.ca/carpalx
Konrad Morawski

1
Đôi khi những lợi ích cận biên của một phương pháp thay thế sẽ đủ lớn để biện minh cho chi phí áp dụng nó; nếu không, tất cả chúng ta vẫn là lập trình lắp ráp và fortran. Câu trả lời này không thực sự trả lời cho câu hỏi ban đầu về việc thực tế có lợi ích cận biên hay không. Trong ví dụ về Dvorak, chắc chắn có và nó đã được chứng minh, nhưng chúng không đủ lợi ích lớn để biện minh cho việc học Dvorak.
Jeremy

@Jeremy "câu trả lời này không thực sự trả lời cho câu hỏi ban đầu về việc thực tế có lợi ích cận biên hay không" - OP không trực tiếp yêu cầu phát hiện các nghiên cứu như vậy, ông hỏi liệu có ai đã cố gắng thực hiện các nghiên cứu đó không, đó là một câu hỏi mở hơn. Tôi đã trả lời bằng cách chỉ ra một vài lý do hợp lý về lý do tại sao nó sẽ khó khăn về mặt kỹ thuật và tại sao bất kỳ kết quả nào của một nghiên cứu như vậy có thể sẽ bị ô nhiễm đáng kể bởi tiếng ồn thống kê. Vì vậy, nếu câu trả lời của tôi được coi là không hữu ích với lý do bạn đưa ra, tôi nghĩ rằng tôi đã bị hạ thấp không công bằng.
Konrad Morawski

1
@Jeremy ý chính của các chi phí áp dụng này là mọi người thực hiện tốt hơn với một công cụ kém hơn miễn là họ đã thực hành nhiều hơn với nó. Và đây chính xác là những gì sẽ xuất hiện trong bất kỳ nghiên cứu nào cố gắng kiểm tra xem các đối tượng của nó đối phó với các phong cách mã hóa khác nhau như thế nào. Tiếng ồn gây ra bởi sự quen thuộc / không quen thuộc trước đó của họ với các kiểu mã hóa mà bạn sử dụng chúng sẽ làm giảm tác động của bất kỳ phẩm chất bẩm sinh nào của các kiểu này. Trừ khi bạn san bằng sân chơi bằng cách chiếm những người mới bắt đầu hoàn thành. Nhưng điều này đặt ra một khó khăn thực tế, như tôi đã chỉ ra trong đoạn cuối của câu trả lời của tôi.
Konrad Morawski

4

Câu trả lời là KHÔNG CÓ! Là `break` và` continue` thực hành lập trình xấu? là một tập hợp con của câu hỏi này, vì vậy tôi sẽ bắt đầu với một câu trả lời hầu như không được sửa đổi cho điều đó ...

Bạn có thể [viết lại] các chương trình mà không có câu lệnh break (hoặc trả về từ giữa các vòng lặp, điều này làm điều tương tự). Nhưng khi làm như vậy, bạn có thể phải giới thiệu các biến bổ sung và / hoặc sao chép mã cả hai điều này thường làm cho chương trình khó hiểu hơn. Pascal (ngôn ngữ lập trình cuối thập niên 1960) rất tệ, đặc biệt đối với những lập trình viên mới bắt đầu vì lý do đó.

Có một kết quả khoa học máy tính được gọi là hệ thống cấu trúc điều khiển của Kosaraju, xuất hiện từ năm 1973 và được đề cập trong bài viết nổi tiếng của Knuth (thêm) lập trình với các báo cáo từ năm 1974. Điều mà S. Rao Kosaraju đã chứng minh vào năm 1973 là nó không phải có thể viết lại tất cả các chương trình có độ sâu đa cấp độ sâu n thành các chương trình có độ sâu ngắt nhỏ hơn n mà không cần đưa ra các biến phụ. Nhưng hãy nói rằng đó chỉ là một kết quả lý thuyết đơn thuần. (Chỉ cần thêm một vài biến số?! Chắc chắn bạn có thể làm điều đó để cảm thấy tập hợp với người dùng 3K + trên stackexchange ...)

Điều quan trọng hơn nhiều từ góc độ công nghệ phần mềm là một bài báo gần đây hơn, năm 1995 của Eric S. Roberts có tiêu đề Loop Exits và Structured Program: Mở lại cuộc tranh luận (doi: 10.1145 / 199688.199815). Roberts tóm tắt một số nghiên cứu thực nghiệm được thực hiện bởi những người khác trước ông. Ví dụ, khi một nhóm sinh viên loại CS101 được yêu cầu viết mã cho một hàm thực hiện tìm kiếm tuần tự trong một mảng, tác giả của nghiên cứu đã nói như sau về những sinh viên đã sử dụng dấu ngắt / quay lại để thoát khỏi chuỗi liên tiếp vòng lặp tìm kiếm ngay khi tìm thấy phần tử:

Tôi vẫn chưa tìm thấy một người nào đã thử một chương trình sử dụng [kiểu này], người đã tạo ra một giải pháp không chính xác.

Roberts cũng nói rằng:

Những sinh viên đã cố gắng giải quyết vấn đề mà không sử dụng một kết quả rõ ràng từ vòng lặp for thì kém hơn rất nhiều: chỉ có bảy trong số 42 sinh viên cố gắng chiến lược này quản lý để tạo ra các giải pháp chính xác. Con số đó thể hiện tỷ lệ thành công dưới 20%.

Có, bạn có thể có nhiều kinh nghiệm hơn sinh viên CS101, nhưng không sử dụng câu lệnh break (hoặc trả lại / goto tương đương từ giữa các vòng lặp), cuối cùng bạn sẽ viết mã mà trong khi có cấu trúc độc đáo là đủ lông về mặt logic bổ sung các biến và sao chép mã mà ai đó, có thể là chính bạn, sẽ đặt các lỗi logic trong đó trong khi cố gắng làm theo một số ý tưởng tuyệt vời về phong cách mã hóa "chính xác".

Và có một vấn đề lớn hơn ở đây ngoài các câu lệnh return / break-type, vì vậy câu hỏi này rộng hơn một chút so với câu hỏi về break. Theo một số cơ chế xử lý ngoại lệ cũng vi phạm mô hình điểm thoát đơn

Vì vậy, về cơ bản, bất cứ ai tranh luận ở trên rằng nguyên tắc thoát đơn lẻ vẫn còn hữu dụng ngày nay cũng đang tranh luận về mô hình xử lý ngoại lệ, trừ khi được sử dụng theo cách cực kỳ hạn chế được mô tả trong liên kết cuối cùng đó; những hướng dẫn đó về cơ bản hạn chế tất cả các ngoại lệ ra khỏi hàm để ném (), tức là không cho phép truyền ngoại lệ giữa các hàm. Thưởng thức Pascal mới của bạn với cú pháp giống như C ++.

Tôi thấy từ đâu mà khái niệm "chỉ một lần trở lại" đến từ đâu?rằng ý kiến ​​phổ biến trên trang web này trái ngược với những gì tôi đã đăng ở đây, vì vậy tôi hoàn toàn hiểu lý do tại sao tôi đã bỏ phiếu xuống, mặc dù tôi là câu trả lời đầu tiên ở đây để thực sự cung cấp một câu hỏi mà câu hỏi yêu cầu: một số thông tin về các bài kiểm tra khả năng sử dụng thực tế tập trung vào vấn đề thoát đơn. Tôi đoán tôi không nên để kiến ​​thức cản trở những định kiến, đặc biệt là trên một trang web chơi game. Tôi sẽ gắn bó với việc chỉnh sửa Wikipedia từ bây giờ. Ít nhất có thông tin từ các nguồn tốt được đánh giá cao và tuyên bố mơ hồ hoặc không chính xác giả vờ được hỗ trợ bởi các nguồn cuối cùng kiếm được lệnh cấm. Trên trang web này, hoàn toàn ngược lại xảy ra: ý kiến ​​không có căn cứ bởi sự thật chi phối. Tôi hoàn toàn mong đợi một mod sẽ xóa phần cuối cùng này, nhưng ít nhất anh chàng đó sẽ biết lý do tại sao bạn mất tôi mãi mãi với tư cách là người đóng góp ở đây.


Tôi đã không đánh giá thấp điều này, nhưng trên "Nhưng khi làm như vậy, bạn có thể phải đưa ra các biến bổ sung và / hoặc sao chép mã cả hai điều này thường làm cho chương trình khó hiểu hơn." điểm, đó là một tuyên bố chủ quan. Tôi đồng ý rằng việc thêm một biến hoặc sao chép mã làm cho khó hiểu, nhưng việc thêm một goto làm cho nó cũng khó hiểu, cộng với có thể giảm thiểu thiệt hại do sao chép bằng cách đưa mã sao chép vào một hàm (mặc dù IMO di chuyển sự phức tạp vào biểu đồ cuộc gọi không tự động loại bỏ nó).
Steve314

Tôi thấy quan điểm của bạn về bài báo năm 1995 chỉ sau bình luận cuối cùng đó, và quyết định nâng cao - điểm thú vị. Tôi nghĩ rằng downvote của bạn có thể nhiều hơn bởi vì bài viết của bạn dài và bắt đầu với một điểm chủ quan, vì vậy có lẽ người downvoter đã không đọc toàn bộ (giống như tôi, lúc đầu). Về cơ bản, đó là một ý tưởng tốt để giới thiệu điểm thực của bạn sớm.
Steve314

Dù sao, tôi nghĩ rất nhiều người nghĩ đến trường hợp ngoại lệ như loại thay thế điểm lối ra thay thế - bởi vì họ đang có nghĩa đối với trường hợp lỗi (loại) họ không thực sự đếm. Tôi hiểu rằng đó là một chút nhạy cảm văn hóa ngôn ngữ, mặc dù. Trong một số ngôn ngữ, "ngoại lệ" không chỉ là tên - một trường hợp thành công đặc biệt là hợp lệ (và IIRC Stroustrup đã nói điều gì đó tương tự về C ++, nêu lên quan điểm triết học về việc liệu lỗi có phải là lỗi nếu được xử lý hay không). Một số người thậm chí còn nói ngoại lệ chỉ là một luồng điều khiển khác để sử dụng bất cứ khi nào nó cung cấp luồng điều khiển mà bạn cần.
Steve314

1
@ Steve314 " cộng với thiệt hại có thể được cho là do sao chép có thể được giảm thiểu bằng cách bao gồm mã được sao chép thành một hàm " Đưa ra khỏi dòng và ra khỏi phần nhìn ngay lập tức của logic của hàm, một phần không có nghĩa gì bị cô lập. Làm cho nó thậm chí khó khăn hơn để hiểu logic của chức năng.
tò mò

1
@cquilguy - vâng, điều đó đúng và có lẽ là một phần trong ý định "chuyển sự phức tạp của tôi vào điểm biểu đồ cuộc gọi" của tôi. Tôn giáo của tôi là mọi lựa chọn bạn đưa ra đều là sự đánh đổi, vì vậy hãy lưu ý đến tất cả các lựa chọn hợp lý cũng như ưu điểm và nhược điểm của chúng, và biết các biện pháp giảm thiểu chung là quan trọng nhưng hãy cẩn thận trong trường hợp phương pháp chữa bệnh còn tệ hơn cả bệnh. Tất nhiên, ngoại trừ một phần của sự đánh đổi là bạn dành bao nhiêu thời gian (hoặc lãng phí) ồn ào về mọi thứ.
Steve314

1

http://dl.acm.org/cites.cfm?id=1241526

http://www.springerlink.com/content/n82qpt83n8735l7t/

http://ieeexplore.ieee.org/xpl/freeabs_all.jsp?arnumber=661092

[Câu hỏi của bạn dường như được trả lời bằng một từ duy nhất, "có". Tuy nhiên, tôi đã được cho biết rằng việc cung cấp các câu trả lời ngắn là "loại bỏ" câu hỏi. Nếu bạn cảm thấy tôi đã từ chối, vui lòng đánh dấu câu trả lời để người điều hành có thể xóa nó.]


1
@ luis.espinal: Hướng tới cái gì? Những thông tin nào sẽ chứa văn bản? Câu hỏi lan man xung quanh một chút. Phần nào của câu hỏi nên được giải quyết với một số văn bản?
S.Lott

1
Là một vấn đề về phong cách, và có lẽ để cung cấp thêm thông tin mà các tóm tắt của các liên kết có thể cung cấp (xem xét rằng chúng tôi không biết liệu OP có phải là thành viên ACM / IEEE / Springer Verlag trả tiền có quyền truy cập vào các bài báo đầy đủ hay không và tìm câu trả lời cho câu hỏi của anh ấy.) Ví dụ, bản tóm tắt bài viết ACM không đề cập đến phong cách mã hóa. Hầu hết nó nói về việc chứng thực định lý chương trình có cấu trúc (bản thân nó không nói về vấn đề trả lại đơn hoặc nhiều lần). Vì vậy, bạn có thể đã giải thích tại sao liên kết đó có liên quan.
luis.espinal

1
Bài viết thứ ba (rất may tôi có quyền truy cập vào IEEE Xplore) dường như không liên quan đến những gì OP đang hỏi theo như tôi có thể nói. Đó là một bài viết tuyệt vời để tâm đến bạn, một bài mà tôi đang in để đọc chuyên dụng hơn vào lần sau. Vì vậy, có lẽ bạn cũng có thể đã giải thích cách bài viết này giúp OP trả lời câu hỏi của anh ấy. Nhìn chung, có vẻ như bạn chỉ đơn giản là đã ném một loạt các liên kết với nhau. Đó không phải là một cách để loại bỏ (trừ khi đó là ý định của bạn), nhưng một lần nữa, tôi không thấy điều đó đã giúp OP như thế nào. Và đây là lý do tại sao một poster nên thêm một số văn bản dọc theo các liên kết của mình. Vì vậy, bây giờ bạn biết lý do tại sao tôi nói điều đó;)
luis.espinal

1
từ miệng của OP Is a coding style principle - e.g. the single-exit principle - really a good thing?- điều đó đặt ra bối cảnh cho câu hỏi mà anh ta đặt ra, về phong cách mã hóa. Hơn nữa, phong cách mã hóa không giống như phương pháp lập trình, đặc biệt là các phương pháp thiết kế cấp cao, vốn là trọng tâm của bài viết của IEEE (được các tác giả nêu rõ.) Đó là lý do tại sao tôi nói "không" - phạm vi hoàn toàn khác nhau.
luis.espinal

1
Tôi nghi ngờ OP đến từ đâu. Anh ấy nói rõ ràng các phong cách mã hóa (không phải phương pháp luận), và đặc biệt, đơn lẻ so với nhiều lợi nhuận. Tôi đã phải đối phó với điều đó một vài lần với mã tự rõ ràng, được viết rõ ràng bằng cách sử dụng nhiều câu lệnh trả lại được viết lại thành các phiên bản phức tạp hơn bằng cách sử dụng trả về đơn (đặc biệt là trong các tổ chức lớn có băng đỏ) * như theo "quá trình". Và người ta tự hỏi (và thách thức với bằng chứng) tính hợp lệ, tính khả dụng và hiệu quả chi phí của các nhiệm vụ tùy tiện như vậy. Những người buộc các nhiệm vụ như vậy vẫn sống trong thập niên 60: /
luis.espinal

1

Là nguyên tắc kiểu mã hóa - ví dụ: nguyên tắc thoát đơn

Những người vẫn quan tâm đến việc một lối thoát đơn hay nhiều lối thoát vẫn bị mắc kẹt vào cuối những năm 1960. Trước đó, một cuộc thảo luận như vậy rất quan trọng vì chúng ta còn ở giai đoạn sơ khai của lập trình viên có cấu trúc, và có khá nhiều trại tuyên bố rằng những phát hiện đằng sau Chương trình cấu trúc Bohm-Jacopini Định lý không thể áp dụng cho tất cả các cấu trúc lập trình.

Đó là một cái gì đó nên được giải quyết từ lâu. Vâng, nó đã được giải quyết (gần 4 thập kỷ là chính xác, trong cả Học viện và ngành công nghiệp), nhưng mọi người (những người hoàn toàn ủng hộ hoặc chống lại) đã không được chú ý.

Đối với phần còn lại của câu trả lời của tôi, tất cả đều tương đối (những gì không có trong phần mềm?):

  • thực sự là một điều tốt?

Vâng. Hầu hết thời gian cho trường hợp chung, với sự cẩn thận cụ thể cho các trường hợp cạnh và cấu trúc lập trình ngôn ngữ cụ thể.

Luôn luôn, hoặc chỉ đôi khi?

Hầu hết thời gian.

Nó thực sự tạo ra bao nhiêu sự khác biệt?

Phụ thuộc.

Mã có thể đọc và mã không thể đọc được. Độ phức tạp tăng (mà chúng ta nên biết bây giờ làm tăng xác suất đưa ra lỗi) so với độ phức tạp đơn giản hơn (và ergo, xác suất lỗi nhỏ hơn.) Các ngôn ngữ có trình biên dịch không thêm trả về ngầm định (giả sử Pascal, Java hoặc C #) và các ngôn ngữ đó mặc định là int (C và C ++).

Cuối cùng, đó là một kỹ năng được mài giũa với người đàn ông / giờ đằng sau bàn phím. Đôi khi, có thể có nhiều câu lệnh trả về, như ở đây (trong một số mã giả Pascal):

function foo() : someType
  begin
  if( test1 == true )
  then
    return x;
  end
  doSomethignElseThatShouldnHappenIfTest1IsTrue();
  return somethingElse();
end;

Mục đích rất rõ ràng và thuật toán đủ nhỏ và không phức tạp đến mức nó không đảm bảo việc tạo ra một biến 'cờ' giữ giá trị trả về cuối cùng được sử dụng trong một điểm trả về duy nhất. Thuật toán có thể bị lỗi, nhưng cấu trúc của nó đủ đơn giản để nỗ lực phát hiện lỗi là (không có khả năng) là không đáng kể.

Đôi khi không phải (ở đây sử dụng mã giả giống như C):

switch(someVal)
{
case v1 : return x1;
case v2 : return x2:
case v3 : doSomething(); // fall-through
case v4: // fall-through
case v5: // fall-through
case v6: return someXthingie;
...
...
default:
   doSomething(); // no return statement yet
}

Ở đây, thuật toán không có cấu trúc đơn giản và câu lệnh chuyển đổi (kiểu C) cho phép các bước rơi qua mà có thể hoặc không được thực hiện một cách có chủ ý như một phần của thuật toán.

Có thể thuật toán là chính xác, nhưng viết kém.

Hoặc có thể, bởi các lực lượng bên ngoài vượt quá khả năng của lập trình viên, đây là đại diện thực tế (và chính xác) của một thuật toán cần thiết hợp pháp.

Có lẽ nó sai.

Để khám phá sự thật của bất kỳ điều này đòi hỏi nỗ lực hơn nhiều so với ví dụ trước. Và đây là điều tôi tin tưởng mạnh mẽ (nhớ rằng tôi không có nghiên cứu chính thức nào để sao lưu điều này):

Giả sử một đoạn mã được coi là chính xác:

  1. Nhiều câu lệnh trả về làm tăng tính dễ đọc và đơn giản của đoạn mã như vậy, nếu đoạn mã biểu thị một thuật toán đơn giản với cấu trúc luồng đơn giản vốn có. Nói một cách đơn giản, tôi không có nghĩa là nhỏ bé, nhưng ý tôi là vốn có thể hiểu được hoặc tự chứng minh , điều đó không đòi hỏi nỗ lực đọc không tương xứng (cũng không khiến mọi người nôn mửa, nguyền rủa mẹ ai đó hoặc nuốt một viên đạn khi họ phải đọc nó. )

  2. Một câu lệnh trả về duy nhất làm tăng tính dễ đọc và đơn giản của một đoạn mã như vậy nếu giá trị trả về được tính trong suốt quá trình thực thi thuật toán hoặc nếu các bước trong thuật toán chịu trách nhiệm tính toán nó có thể được nhóm lại với nhau tại một vị trí trong cấu trúc của thuật toán .

  3. Một câu lệnh trả về duy nhất làm giảm tính dễ đọc và đơn giản của một đoạn mã như vậy nếu nó yêu cầu các phép gán cho một hoặc nhiều biến cờ, với các vị trí của các phép gán đó không được định vị thống nhất trong suốt thuật toán.

  4. Nhiều câu lệnh trả về làm giảm tính dễ đọc và đơn giản của một đoạn mã như vậy nếu các câu lệnh trả lại không được phân phối đồng đều trên thuật toán và nếu chúng phân định các khối mã loại trừ lẫn nhau không đồng nhất về kích thước hoặc cấu trúc.

Điều này liên quan chặt chẽ đến sự phức tạp của một đoạn mã được đề cập. Và điều này đến lượt nó có liên quan đến các biện pháp phức tạp chu kỳ và halstead. Từ điều này, người ta có thể quan sát như sau:

Kích thước của chương trình con hoặc hàm càng lớn, cấu trúc luồng điều khiển bên trong của nó càng lớn và phức tạp hơn, và xác suất bạn sẽ phải đối mặt với một câu hỏi về việc nên sử dụng nhiều câu lệnh trả lại hay đơn.

Kết luận của việc này là: giữ cho các chức năng của bạn nhỏ làm một việc và chỉ một việc (và thực hiện tốt). Nếu chúng thể hiện các số liệu độ phức tạp nhỏ và chu kỳ trên danh nghĩa, không chỉ chúng bị ràng buộc là chính xác nhất và được thực hiện các nhiệm vụ có thể hiểu được, cấu trúc bên trong của chúng cũng sẽ tương đối rõ ràng.

Sau đó, và chỉ sau đó bạn có thể khá dễ dàng và không mất nhiều giấc ngủ, bạn có thể quyết định có nên sử dụng một lần trả lại và nhiều lần trả lại mà không gặp nhiều rủi ro khi đưa ra các lỗi với một trong hai lựa chọn hay không.

Người ta cũng có thể xem xét tất cả những điều này và đề nghị rằng khi mọi người đấu tranh với vấn đề trả lại một lần hoặc nhiều lần trả lại, đó là bởi vì - do thiếu kinh nghiệm, ngu ngốc hoặc thiếu đạo đức công việc - họ không viết mã sạch và có xu hướng viết chức năng quái dị với sự coi thường hoàn toàn các biện pháp chu kỳ và halstead.


1
Kiểu trả về C ++ không mặc định thành int: không có kiểu trả về mặc định nên nó phải được chỉ định trong mọi trường hợp.
Sjoerd

Từ trước khi tôi viết câu hỏi này - lập trình viên.stackexchange.com / questions / 53737 / . Về cơ bản, tôi ủng hộ nhận thức về nguyên tắc này, nhưng không tuân thủ nghiêm ngặt - nếu tất cả các điểm thoát là rõ ràng, tôi rất vui. Quan điểm của tôi ở đây - chỉ vì tôi đề cập đến một nguyên tắc như một ví dụ không có nghĩa là tôi ủng hộ nguyên tắc đó, và chắc chắn không phải ở dạng nghiêm ngặt. Tuy nhiên, ý kiến ​​chủ quan của tôi chỉ là như vậy - có thể có một lập luận mạnh mẽ hơn cho quan điểm của tôi, hoặc có thể có một lập luận mạnh mẽ rằng tôi đã sai.
Steve314

"Mặc định cho int" là gì?
tò mò

Ý tôi là, và tôi nên có đủ điều kiện, hầu hết các trình biên dịch sẽ chỉ đơn giản là "chuyển" giá trị của thanh ghi tích lũy thành giá trị trả về nếu mã xảy ra có nhánh thực thi với giá trị trả về rõ ràng. Điều đó có hiệu lực có nghĩa là trả về kết quả của phép toán số học cuối cùng (bất kỳ rác nào có thể) ở dạng int. Và đó chắc chắn sẽ là rác (và ergo, hành vi không xác định) bất kể chức năng dự định làm gì ở nơi đầu tiên. C và C ++ có thể cảnh báo bạn, nhưng biên dịch sẽ cho phép bạn biên dịch trừ khi bạn sử dụng -Werror hoặc một cái gì đó tương tự.
luis.espinal
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.