it-swarm-vi.com

Điều gì được chứng minh là độ dài tối đa tốt của hàm?

Liệu chiều dài chức năng có ảnh hưởng đến năng suất của một lập trình viên? Nếu vậy, số dòng tối đa tốt để tránh mất năng suất là gì?

Vì đây là một chủ đề được đánh giá cao, vui lòng sao lưu khiếu nại với một số dữ liệu.

47
Gaurav

Kể từ khi tôi bắt tay vào cây vợt điên rồ này vào năm 1970, tôi đã thấy chính xác một mô-đun thực sự cần thiết để có nhiều hơn một trang in (khoảng 60 dòng). Tôi đã thấy rất nhiều mô-đun dài hơn.

Đối với vấn đề đó, tôi đã viết các mô-đun dài hơn, nhưng chúng thường là các máy trạng thái hữu hạn lớn được viết dưới dạng các câu lệnh chuyển đổi lớn.

Một phần của vấn đề dường như là các lập trình viên ngày nay không được dạy để mô đun hóa mọi thứ.

Các tiêu chuẩn mã hóa tối đa hóa sự lãng phí của không gian dọc dường như cũng là một phần của vấn đề. (Tôi có chưa để gặp người quản lý phần mềm đã đọc Gerald Weinberg 's " Tâm lý học lập trình máy tính ". Weinberg chỉ ra rằng nhiều nghiên cứu đã chỉ ra rằng sự hiểu biết của lập trình viên về cơ bản chỉ giới hạn ở những gì lập trình viên có thể thấy tại bất kỳ thời điểm nào. Nếu lập trình viên phải cuộn, hoặc lật một trang, mức độ hiểu của họ giảm đáng kể: họ phải nhớ và trừu tượng.)

Tôi vẫn tin rằng rất nhiều sự tăng năng suất của lập trình viên được chứng minh bằng tài liệu từ RA là do hệ thống "chặn" FORTH cho mã nguồn: các mô-đun rất khó- giới hạn tối đa tuyệt đối 16 dòng 64 ký tự. Bạn có thể tính hệ số vô hạn, nhưng bạn không thể trong bất kỳ trường hợp nào viết thói quen 17 dòng.

47
John R. Strohm

Kích thước phù hợp, thực sự?

Phụ thuộc vào ngôn ngữ bạn sử dụng, nhưng nói chung (và theo sở thích cá nhân của tôi):

  • Lý tưởng nhất , dưới 25 dòng.
  • Chấp nhận được , dưới 35 dòng.

Nếu nó nhiều hơn, thì đó là thứ tôi cần quay lại sau và làm lại.

Nhưng thực tế , bất kỳ kích thước nào cần có khi bạn cần cung cấp một cái gì đó và điều đó có ý nghĩa hơn vào lúc này để nhổ chúng ra như thế, làm cho đôi khi còn dễ dàng hơn cho ai đó để xem xét trước khi vận chuyển. (nhưng vẫn lấy lại được sau).

(Gần đây, nhóm của tôi đã chạy một chương trình trên cơ sở mã của chúng tôi: chúng tôi đã tìm thấy lớp có 197 phương thức và một phương thức khác chỉ có 3 phương thức nhưng một trong số đó là 600 dòng. Trò chơi dễ thương: điều gì tệ hơn trong 2 tệ nạn?)


Bây giờ để có câu trả lời zen hơn ... Nói chung, nó được coi là một cách thực hành tốt (TM) để trích dẫn một hoặc hai người đàn ông tuyệt vời, vì vậy hãy vào đây:

Mọi thứ nên được làm đơn giản nhất có thể, nhưng không đơn giản hơn. - A. Einstein

Sự hoàn hảo cuối cùng đạt được không phải khi không còn gì để thêm, mà là khi không còn gì để lấy đi. - A. De Saint Xuất thần


Phụ lục về kiểu bình luận

Là một phụ lục cho điều này, các chức năng của bạn nên có tên rõ ràng giải thích ý định của chúng. Về ý kiến, tôi thường không bình luận bên trong một chức năng:

  • nhận xét nói "tại sao?" ,
  • cho biết "làm thế nào?" .

Một khối nhận xét ở đầu mỗi chức năng (yêu cầu giải thích) là đủ. Nếu chức năng của bạn nhỏ và tên hàm đủ rõ ràng, thì bạn chỉ cần nói những gì bạn muốn đạt được và tại sao. Tôi chỉ sử dụng nhận xét nội tuyến cho các trường trong một số ngôn ngữ hoặc trên khối bắt đầu cho các chức năng phá vỡ quy tắc dòng 25-35 đó nếu mục đích không rõ ràng. Tôi sử dụng một nhận xét khối bên trong mã khi xảy ra tình huống đặc biệt (ví dụ: khối bắt mà bạn không cần hoặc muốn làm bất cứ điều gì nên có một nhận xét cho biết tại sao, ví dụ).

Để biết thêm, vui lòng đọc câu trả lời của tôi trên Phong cách và đề xuất về mã nhận xét

31
haylem

Theo tôi, mọi chức năng nên càng nhỏ càng tốt. Mỗi chức năng chỉ nên làm một việc và làm tốt. Điều đó không thực sự trả lời câu hỏi về độ dài tối đa, nhưng cảm nhận của tôi nhiều hơn về độ dài của các chức năng.

Để sử dụng những lời của chú Bob, "Trích xuất cho đến khi bạn có thể trích xuất thêm nữa. Trích xuất cho đến khi bạn thả."

12
Jason

Chiều cao tối đa của một tòa nhà là bao nhiêu? Phụ thuộc vào vị trí của bản dựng hoặc chiều cao bạn muốn.
[.__.] Bạn có thể nhận được câu trả lời khác nhau từ những người khác nhau đến từ thành phố khác nhau.
[.__.] Một số hàm script và trình xử lý ngắt kernel rất dài.

10
Huang F. Lei

Một phương pháp phù hợp với tôi là: Tôi có thể có một phần của hàm dài hơn đặt tên có ý nghĩa không. Tôi nghĩ độ dài của một phương thức không quan trọng bằng việc đặt tên tốt. Phương pháp nên làm những gì tên nói, không hơn không kém. Và bạn sẽ có thể đặt một cái tên hay. Nếu bạn không thể đặt tên cho phương thức của mình là tốt, thì mã có thể không được đặt cùng nhau.

10
Mnementh

Miễn là nó cần phải làm những gì nó cần làm, nhưng không còn nữa.

10
Paul Nathan

Tôi nghĩ rằng có một sự đánh đổi. Nếu bạn có nhiều phương thức ngắn, việc gỡ lỗi chúng thường khó hơn một phương thức dài. Nếu bạn phải nhảy xung quanh trình soạn thảo 20 hoặc 30 lần khác nhau để theo dõi một cuộc gọi phương thức, sẽ rất khó để giữ tất cả trong đầu. Trong khi đó, nếu có một phương pháp rõ ràng được viết tốt, ngay cả khi nó là 100 dòng, việc giữ trong đầu bạn thường dễ dàng hơn.

Câu hỏi thực sự là tại sao các mục nên ở các phương thức khác nhau và câu trả lời như đã nêu ở trên là sử dụng lại mã. Nếu bạn không sử dụng lại mã (hoặc không biết) thì có thể để lại mã theo một phương pháp dễ thực hiện và sau đó khi bạn cần sử dụng lại, hãy chia các phần cần tái sử dụng sử dụng thành các phương pháp nhỏ hơn.

Trong thực tế, một phần của thiết kế phương pháp tốt là tạo ra các phương thức gắn kết chức năng (về cơ bản chúng làm một việc). Độ dài của các phương pháp không quan trọng. Nếu một hàm thực hiện một điều được xác định rõ và là 1.000 dòng thì đó là một phương thức tốt. Nếu một hàm thực hiện 3 hoặc 4 điều và chỉ có 15 dòng, thì đó là một phương pháp tồi ...

6
Cervo

Từ Độ phức tạp theo chu kỳ (Wikipedia):

Độ phức tạp chu kỳ của một phần của mã nguồn là số lượng các đường dẫn độc lập tuyến tính thông qua mã nguồn.

  • Tôi khuyên bạn nên giữ số đó dưới 10 trong một phương pháp duy nhất. Nếu nó lên 10, thì đã đến lúc phải tính lại.

  • Có những công cụ có thể đánh giá mã của bạn và cung cấp cho bạn số phức tạp theo chu kỳ.

  • Bạn nên cố gắng tích hợp các công cụ này vào đường ống xây dựng của bạn.

  • Đừng theo đuổi một kích thước phương pháp theo nghĩa đen, nhưng hãy thử xem xét độ phức tạp và trách nhiệm của nó. Nếu nó có nhiều hơn một trách nhiệm, thì có lẽ nên tái lập yếu tố. Nếu độ phức tạp chu kỳ của nó tăng lên, thì có lẽ đã đến lúc phải tính lại.

  • Tôi khá chắc chắn có những công cụ khác cung cấp cho bạn thông tin phản hồi tương tự, nhưng tôi chưa có cơ hội để xem xét vấn đề này.

5
CodeART

Đối với tôi, một hàm là bất kỳ độ dài nào nó cần phải có. Hầu hết thời gian tôi chia nó là khi tôi sẽ sử dụng lại mã.

Về cơ bản, tôi sẽ tuân theo nguyên tắc 'sự gắn kết cao, khớp nối thấp' và không có ràng buộc về chiều dài.

5
Ross

Câu hỏi nên có bao nhiêu điều một chức năng nên làm. Và thông thường, thật hiếm khi bạn cần 100 dòng để thực hiện "một". Một lần nữa, điều đó phụ thuộc vào mức độ bạn đang xem mã: Việc băm mật khẩu có phải là một điều không? Hoặc là băm và lưu mật khẩu một điều?

Tôi muốn nói, hãy bắt đầu với việc lưu mật khẩu như một chức năng. Khi bạn cảm thấy băm là khác nhau, và bạn cấu trúc lại mã. Tôi không phải là chuyên gia lập trình bằng bất kỳ phương tiện nào, nhưng IMHO, toàn bộ ý tưởng về các hàm bắt đầu nhỏ là các hàm của bạn càng nguyên tử, cơ hội sử dụng lại mã càng cao, không bao giờ phải thay đổi giống nhau ở nhiều nơi , Vân vân.

Tôi đã thấy SQL thủ tục được lưu trữ chạy hơn 1000 dòng. Có phải số lượng dòng thủ tục lưu trữ cũng ít hơn 50? Tôi không biết, nhưng nó làm cho việc đọc mã, chết tiệt. Bạn không chỉ phải tiếp tục cuộn lên xuống, bạn cần đặt một vài dòng mã như "cái này không xác thực1", "bản cập nhật này trong cơ sở dữ liệu", v.v. - một công việc mà lập trình viên nên làm.

5
Narayana

Tôi thấy dễ dàng hơn để theo dõi những gì tôi đang làm nếu tôi có thể thấy toàn bộ chức năng cùng một lúc. Vì vậy, đây là cách tôi thích viết hàm:

  1. Đủ ngắn để phù hợp với màn hình của tôi với một phông chữ hợp lý.
  2. Nếu nó cần dài hơn # 1, đủ ngắn để in trên một tờ giấy trong một phông chữ hợp lý.
  3. Nếu nó cần dài hơn # 2, đủ ngắn để in 2-up lên một tờ giấy.

Tôi hiếm khi viết các chức năng lâu hơn thế. Hầu hết trong số đó là các câu lệnh chuyển đổi C/C++ khổng lồ.

5
Bob Murphy

Đủ ngắn để được tối ưu hóa chính xác

Các phương pháp nên ngắn gọn để làm chính xác một điều. Lý do cho điều này là đơn giản: vì vậy mã của bạn có thể được tối ưu hóa đúng.

Trong ngôn ngữ JIT-ted như Java hoặc C #, điều quan trọng là các phương thức của bạn phải đơn giản để trình biên dịch JIT có thể tạo mã nhanh chóng. Các phương thức dài hơn, phức tạp hơn đòi hỏi nhiều thời gian JIT hơn. Ngoài ra, trình biên dịch JIT chỉ cung cấp một số tối ưu hóa và chỉ các phương thức đơn giản nhất được hưởng lợi từ việc này. Thực tế này thậm chí còn được gọi ra trong Bill Wagner C # hiệu quả .

Trong ngôn ngữ cấp thấp hơn, như C hoặc C++, việc có các phương thức ngắn (có thể là hàng tá dòng) cũng rất quan trọng vì cách đó giúp bạn giảm thiểu nhu cầu lưu trữ các biến cục bộ trong RAM thay vì trong một thanh ghi. (Aka 'Đăng ký đổ'.) Lưu ý tuy nhiên trong trường hợp không được quản lý này, chi phí tương đối của mỗi lệnh gọi hàm có thể khá cao.

Và ngay cả trong một ngôn ngữ động, như Ruby hoặc Python, việc có các phương thức ngắn cũng giúp tối ưu hóa trình biên dịch. Trong một ngôn ngữ động, một tính năng càng 'động', càng khó tối ưu hóa. Ví dụ: một phương thức dài lấy X và có thể trả về Int, Float hoặc String có thể sẽ hoạt động chậm hơn nhiều so với ba phương thức riêng biệt mà mỗi phương thức chỉ trả về một loại duy nhất. Điều này là do, nếu trình biên dịch biết chính xác loại nào chức năng sẽ trở lại, nó cũng có thể tối ưu hóa trang web gọi chức năng. (Ví dụ: không kiểm tra chuyển đổi loại.)

4
Chris Smith

Thông thường, tôi cố gắng giữ các phương thức/chức năng của mình phù hợp với màn hình của màn hình 1680x1050. Nếu nó không phù hợp, sau đó sử dụng các phương thức/hàm trợ giúp để phân chia nhiệm vụ.

Nó giúp dễ đọc trên cả màn hình và giấy.

4
Jason

Tôi không đặt giới hạn cứng cho bất cứ điều gì vì một số hàm thực hiện các thuật toán vốn đã phức tạp và bất kỳ nỗ lực nào để làm cho chúng ngắn hơn sẽ làm cho các tương tác giữa các hàm mới, ngắn hơn trở nên phức tạp đến mức không thể giảm được sự đơn giản. Tôi cũng không tin rằng một chức năng chỉ nên làm "một việc" là một hướng dẫn tốt, vì "một điều" ở mức độ trừu tượng cao có thể là "nhiều việc" ở cấp độ thấp hơn.

Đối với tôi, một hàm chắc chắn quá dài nếu độ dài của nó gây ra vi phạm tinh vi DRY ngay bây giờ và trích xuất một phần của hàm vào một hàm hoặc lớp mới có thể giải quyết điều này. lâu nếu đây không phải là trường hợp, nhưng một chức năng hoặc lớp có thể dễ dàng được trích xuất sẽ làm cho mã trở nên mô đun hơn theo cách có thể hữu ích khi đối mặt với sự thay đổi có thể thấy trước.

4
dsimcha

Nó phụ thuộc rất nhiều vào những gì trong mã.

Tôi đã thấy một thói quen hàng ngàn dòng mà tôi không có vấn đề với. Đó là một tuyên bố chuyển đổi lớn, không có tùy chọn nào vượt quá một chục dòng và cấu trúc điều khiển duy nhất trong bất kỳ tùy chọn nào là một vòng lặp. Ngày nay, nó đã được viết bằng các đối tượng nhưng đó không phải là một lựa chọn trước đó.

Tôi cũng đang nhìn vào 120 dòng trong một công tắc trước mặt tôi. Không có trường hợp nào vượt quá 3 dòng - một người bảo vệ, một nhiệm vụ và phá vỡ. Đó là phân tích một tệp văn bản, các đối tượng không có khả năng. Bất kỳ thay thế sẽ khó đọc hơn.

3
Loren Pechtel

Hầu hết các trình biên dịch không quan tâm đến độ dài của hàm. Một chức năng nên có chức năng, nhưng phải dễ hiểu, thay đổi và tái sử dụng cho con người. Chọn một chiều dài phù hợp với bạn nhất.

2
LennyProgrammers

Có lẽ chiều dài chức năng không phải là một số liệu tốt. Chúng tôi cố gắng sử dụng độ phức tạp chu kỳ , trên các phương thức và một trong các quy tắc kiểm tra kiểm soát nguồn trong tương lai rằng độ phức tạp chu kỳ trên các lớp và phương thức phải thấp hơn X.

Đối với các phương thức, X được đặt thành 30 và khá chặt chẽ.

1
Antonio Bakula

Nguyên tắc chung của tôi là một chức năng phải phù hợp trên màn hình. Chỉ có ba trường hợp tôi thấy có xu hướng vi phạm điều này:

1) Chức năng điều phối. Ngày xưa, những thứ này là phổ biến nhưng hầu hết chúng được thay thế bằng sự kế thừa đối tượng ngày nay. Tuy nhiên, các đối tượng chỉ hoạt động bên trong chương trình của bạn và do đó bạn sẽ vẫn thấy các chức năng điều phối thỉnh thoảng khi xử lý dữ liệu đến từ nơi khác.

2) Các chức năng thực hiện một loạt các bước để hoàn thành mục tiêu và trong đó các bước thiếu một phân ngành tốt. Bạn kết thúc với một hàm chỉ đơn giản gọi một danh sách dài các hàm khác theo thứ tự.

3) Giống như # 2 nhưng trong đó các bước riêng lẻ quá nhỏ đến mức chúng chỉ được nội tuyến đơn giản thay vì được gọi riêng.

1
Loren Pechtel