Độ dài lý tưởng của một phương pháp cho bạn là gì? [đóng cửa]


122

Trong lập trình hướng đối tượng, tất nhiên không có quy tắc chính xác nào về độ dài tối đa của một phương thức, nhưng tôi vẫn thấy hai trích dẫn này hơi mâu thuẫn với nhau, vì vậy tôi muốn nghe bạn nghĩ gì.

Trong mã sạch: Cẩm nang về nghề thủ công phần mềm linh hoạt , Robert Martin nói:

Nguyên tắc đầu tiên của chức năng là chúng phải nhỏ. Quy tắc thứ hai của các chức năng là chúng phải nhỏ hơn thế. Các chức năng không được dài 100 dòng. Các chức năng hầu như không bao giờ dài 20 dòng.

và anh ta đưa ra một ví dụ từ mã Java mà anh ta thấy từ Kent Beck:

Mỗi chức năng trong chương trình của ông chỉ dài hai, hoặc ba hoặc bốn dòng. Mỗi cái đều rõ ràng. Mỗi người kể một câu chuyện. Và từng dẫn bạn đến tiếp theo theo thứ tự hấp dẫn. Đó là cách chức năng của bạn nên ngắn!

Điều này nghe có vẻ hay, nhưng mặt khác, trong Code Complete , Steve McConnell lại nói một điều rất khác:

Thói quen nên được cho phép phát triển hữu cơ lên ​​tới 100-200 dòng, hàng thập kỷ bằng chứng nói rằng các thói quen có độ dài như vậy không có nhiều lỗi dễ xảy ra sau đó là các thói quen ngắn hơn.

Và ông đưa ra một tài liệu tham khảo cho một nghiên cứu nói rằng thói quen 65 dòng hoặc dài là rẻ hơn để phát triển.

Vì vậy, trong khi có những ý kiến ​​khác nhau về vấn đề này, có một thực hành chức năng tốt nhất cho bạn?


17
Chức năng nên dễ hiểu. Độ dài nên theo đó, tùy thuộc vào hoàn cảnh.
Henk Holterman

56
Tôi nghĩ rằng giới hạn thực sự là ở 53 dòng. Với kích thước dòng trung bình là 32,4 ký tự. Nghiêm túc mà nói, không có câu trả lời dứt khoát. Một phương pháp 100 dòng có thể rất rõ ràng và có thể duy trì được, và một phương pháp 4 dòng có thể là một cơn ác mộng để hiểu. Nói chung, mặc dù, các phương thức dài có xu hướng có quá nhiều trách nhiệm, và khó hiểu và duy trì hơn các phương pháp nhỏ hơn. Tôi sẽ suy nghĩ về mặt trách nhiệm và cố gắng có một trách nhiệm duy nhất cho mỗi phương pháp.

23
Có một thuật ngữ trong lập trình được gọi là sự kết hợp chức năng của thành phố. Độ dài của một hàm nên được cho phép thay đổi miễn là việc triển khai của nó vẫn tạo thành một đơn vị logic kết hợp duy nhất trong ứng dụng của bạn. Việc phân tách các hàm một cách tùy tiện để làm cho chúng nhỏ hơn có nhiều khả năng làm sai mã của bạn và làm tổn thương khả năng bảo trì.

9
Và, nếu bạn muốn giới hạn độ phức tạp của các chức năng, bạn nên đo độ phức tạp theo chu kỳ của chúng , chứ không phải độ dài của chúng. Một switchtuyên bố với 100 caseđiều kiện có thể duy trì nhiều hơn 10 cấp độ của các ifcâu lệnh được lồng vào nhau.

10
Cách tiếp cận của Bob Martin là từ năm 2008, Steve Mc Connell `từ năm 1993. Họ có những triết lý khác nhau về" mã tốt "là gì và IMHO Bob Martin cố gắng đạt được mức chất lượng mã cao hơn nhiều.
Doc Brown

Câu trả lời:


115

Các hàm thường phải ngắn, giữa 5-15 dòng là "quy tắc ngón tay cái" cá nhân của tôi khi mã hóa bằng Java hoặc C #. Đây là một kích thước tốt vì nhiều lý do:

  • Nó phù hợp dễ dàng trên màn hình của bạn mà không cần cuộn
  • Đó là về kích thước khái niệm mà bạn có thể giữ trong đầu
  • Nó đủ ý nghĩa để yêu cầu một chức năng theo đúng nghĩa của nó (như một đoạn logic độc lập, có ý nghĩa)
  • Hàm nhỏ hơn 5 dòng là một gợi ý rằng có lẽ bạn đang phá mã quá nhiều (điều này khiến bạn khó đọc / hiểu hơn nếu bạn cần điều hướng giữa các hàm). Hoặc là hoặc bạn đang quên các trường hợp đặc biệt / xử lý lỗi của bạn!

Nhưng tôi không nghĩ sẽ hữu ích khi đặt quy tắc tuyệt đối, vì sẽ luôn có ngoại lệ / lý do hợp lệ để phân kỳ khỏi quy tắc:

  • Hàm truy cập một dòng thực hiện phân loại kiểu rõ ràng có thể chấp nhận được trong một số trường hợp.
  • Có một số chức năng rất ngắn nhưng hữu ích (ví dụ: trao đổi như người dùng chưa biết) rõ ràng cần ít hơn 5 dòng. Không phải là vấn đề lớn, một vài hàm 3 dòng không gây hại cho cơ sở mã của bạn.
  • Hàm 100 dòng là một câu lệnh chuyển đổi lớn duy nhất có thể được chấp nhận nếu nó cực kỳ rõ ràng những gì đang được thực hiện. Mã này có thể rất đơn giản về mặt khái niệm ngay cả khi nó đòi hỏi nhiều dòng để mô tả các trường hợp khác nhau. Đôi khi có ý kiến ​​cho rằng điều này nên được tái cấu trúc thành các lớp riêng biệt và được triển khai bằng cách sử dụng tính kế thừa / đa hình nhưng IMHO điều này đang đưa OOP đi quá xa - tôi chỉ muốn có một câu lệnh chuyển đổi 40 chiều lớn hơn 40 lớp mới để xử lý, ngoài ra đến một câu lệnh chuyển đổi 40 chiều để tạo ra chúng.
  • Một hàm phức tạp có thể có rất nhiều biến trạng thái sẽ rất lộn xộn nếu được chuyển giữa các hàm khác nhau làm tham số. Trong trường hợp này, bạn có thể đưa ra một lập luận hợp lý rằng mã đơn giản và dễ theo dõi hơn nếu bạn giữ mọi thứ trong một hàm lớn duy nhất (mặc dù như Mark chỉ ra một cách đúng đắn, đây cũng có thể là một ứng cử viên để biến thành một lớp để gói gọn cả logic và nhà nước).
  • Đôi khi các chức năng nhỏ hơn hoặc lớn hơn có lợi thế về hiệu suất (có lẽ vì lý do nội tuyến hoặc JIT như Frank đề cập). Điều này phụ thuộc rất nhiều vào việc thực hiện, nhưng nó có thể tạo ra sự khác biệt - đảm bảo bạn đạt điểm chuẩn!

Vì vậy, về cơ bản, hãy sử dụng thông thường , tuân theo các kích thước chức năng nhỏ trong hầu hết các trường hợp nhưng đừng giáo điều về nó nếu bạn có lý do thực sự tốt để thực hiện một chức năng lớn bất thường.


9
Cũng có một lý do kỹ thuật / hoàn hảo cho các phương pháp ngắn: các lần truy cập bộ đệm JIT. Nhiều phương pháp nhỏ hơn, có thể tái sử dụng có nhiều khả năng đã được gọi trước đây. Oh và một lợi ích bổ sung, StackTraces tập trung nhiều hơn vào logic đã xuất hiện.
Luke Puplett

20
"sử dụng thông thường" là lời khuyên quan trọng nhất
Simon

Mọi người nên biết rằng heuristic này sẽ dẫn đến khiếu nại về "mã ravioli" do độ sâu của ngăn xếp trong các điểm dừng, khi gỡ lỗi.
Frank Hileman

5
@FrankHileman Tôi sẽ dùng ravioli qua spaghetti bất cứ ngày nào khi viết mã

1
@Snowman: những lựa chọn này không loại trừ lẫn nhau ... độ sâu ngăn xếp ngắn mà không có spaghetti là lý tưởng. Sâu ngăn xếp sâu, với spaghetti ở bên?
Frank Hileman

30

Mặc dù tôi đồng ý với ý kiến ​​của người khác khi họ nói rằng không có quy tắc cứng nào về số LỘC phải, tôi cá là nếu chúng ta nhìn lại các dự án mà chúng ta đã xem trong quá khứ và xác định mọi chức năng ở trên, hãy nói 150 dòng mã, tôi ' Tôi đoán chúng ta sẽ đi đến thống nhất rằng 9 trong số 10 chức năng đó phá vỡ SRP (và rất có thể là OCP), có quá nhiều biến cục bộ, quá nhiều luồng điều khiển và thường khó đọc và duy trì.

Vì vậy, trong khi LỘC có thể không phải là một chỉ báo trực tiếp về mã xấu, thì chắc chắn đó là một chỉ báo gián tiếp đàng hoàng rằng chức năng nhất định có thể được viết tốt hơn.

Trong đội của tôi, tôi rơi vào vị trí dẫn đầu và vì bất kỳ lý do gì, mọi người dường như đang lắng nghe tôi. Những gì tôi thường giải quyết là nói với nhóm rằng trong khi không có giới hạn tuyệt đối, thì bất kỳ chức năng nào, hơn 50 dòng mã sẽ tối thiểu giơ cờ đỏ trong quá trình xem xét mã, để chúng tôi xem xét lại và đánh giá lại nó cho sự phức tạp và vi phạm SRP / OCP. Sau cái nhìn thứ hai đó, chúng ta có thể để nó một mình hoặc chúng ta có thể thay đổi nó, nhưng ít nhất nó khiến mọi người nghĩ về những điều này.


3
Điều này có vẻ hợp lý - LỘC không có nghĩa là bất cứ điều gì liên quan đến độ phức tạp hoặc chất lượng mã, nhưng nó có thể là một dấu hiệu tốt cho khả năng mọi thứ nên được tái cấu trúc.
cori

4
"đi đến thống nhất rằng 9 trong số 10 chức năng đó phá vỡ SRP" - Tôi không đồng ý, tôi khá chắc chắn 10 trong số 10 chức năng đó sẽ phá vỡ nó ;-)
Doc Brown

1
+1 để tăng cờ trong quá trình xem xét mã: nói cách khác, không phải là quy tắc khó và nhanh, nhưng hãy thảo luận về mã này với tư cách một nhóm.

22

Tôi bước vào một dự án mà không quan tâm đến các hướng dẫn mã hóa. Khi tôi nhìn vào mã, đôi khi tôi thấy các lớp có hơn 6000 dòng mã và ít hơn 10 phương thức. Đây là một kịch bản kinh dị khi bạn phải sửa lỗi.

Một quy tắc chung về mức độ lớn nhất của một phương pháp đôi khi không tốt lắm. Tôi thích quy tắc của Robert C. Martin (Chú Bob): "Phương pháp nên nhỏ, nhỏ hơn nhỏ". Tôi cố gắng sử dụng quy tắc này mọi lúc. Tôi đang cố gắng giữ cho các phương thức của mình đơn giản và nhỏ bằng cách làm rõ rằng phương thức của tôi chỉ làm một việc và không có gì hơn.


4
Tôi không thấy lý do tại sao hàm 6000 dòng khó gỡ lỗi hơn hàm ngắn hơn ... Trừ khi nó cũng có vấn đề khác (ví dụ: sự lặp lại)
Calmarius

17
Nó không có gì để làm với gỡ lỗi .. đó là về sự phức tạp và khả năng bảo trì. Làm thế nào bạn sẽ mở rộng hoặc thay đổi một phương pháp 6000 dòng được thực hiện bởi một phương pháp khác?
Khói chân

10
@Calmarius sự khác biệt thường là 6000 hàm dòng có xu hướng chứa các biến cục bộ được khai báo rất xa (trực quan), khiến lập trình viên khó xây dựng bối cảnh tinh thần cần có độ tin cậy cao về mã. Bạn có thể chắc chắn về cách một biến được khởi tạo và xây dựng tại bất kỳ điểm nào không? Bạn có chắc chắn không có gì sẽ gây rối với biến của mình sau khi bạn đặt nó trên dòng 3879 không? Mặt khác, với 15 phương thức đường, bạn có thể chắc chắn.
Daniel B

8
@Calmarius đồng ý, nhưng cả hai tuyên bố này là một đối số chống lại 6000 hàm LỘC.
Daniel B

2
Một biến cục bộ trong phương thức 600 dòng thực chất là biến toàn cục.
MK01

10

Nó không phải là về số lượng dòng, nó là về SRP. Theo nguyên tắc này, phương pháp của bạn nên làm một và chỉ một điều.

Nếu phương thức của bạn thực hiện điều này VÀ điều này VÀ điều này HOẶC điều đó => thì có lẽ nó đang làm rất nhiều. Hãy thử xem phương pháp này và phân tích: "ở đây tôi lấy dữ liệu này, sắp xếp nó và lấy các yếu tố tôi cần" và "ở đây tôi xử lý các yếu tố này" và "ở đây cuối cùng tôi đã kết hợp chúng để có kết quả". Các "khối" này nên được cấu trúc lại thành các phương thức khác.

Nếu bạn chỉ cần làm theo SRP, hầu hết phương pháp của bạn sẽ nhỏ và có ý định rõ ràng.

Thật không đúng khi nói "phương pháp này là> 20 dòng nên nó sai". Nó có thể là một dấu hiệu cho thấy một cái gì đó có thể sai với phương pháp này, không còn nữa.

Bạn có thể có một chuyển đổi 400 dòng trong một phương thức (thường xảy ra trong viễn thông), và nó vẫn là trách nhiệm duy nhất và nó hoàn toàn ổn.


2
Các câu lệnh chuyển đổi lớn, định dạng đầu ra, định nghĩa của băm / từ điển nên được mã hóa cứng thay vì linh hoạt trong một số cơ sở dữ liệu, điều này thường xảy ra và hoàn toàn tốt. Miễn là logic bị lệch, thì bạn đều ổn cả. Một phương pháp lớn có thể khiến bạn nghĩ rằng 'tôi nên chia cái này'. Câu trả lời rất có thể là 'không, điều này cũng tốt' (hoặc vâng, đây là một mớ hỗn độn tuyệt đối)
Martijn

"SRP" có nghĩa là gì?
thomthom

3
SRP là viết tắt của Nguyên tắc Trách nhiệm Đơn lẻ và tuyên bố rằng mỗi lớp (hoặc phương thức) chỉ nên có một trách nhiệm. Nó liên quan đến sự gắn kết và khớp nối. Nếu bạn theo SRP, các lớp (hoặc phương thức) của bạn sẽ có sự gắn kết tốt, nhưng việc ghép có thể tăng lên vì bạn kết thúc với nhiều lớp (hoặc phương thức) hơn.
Kristian Duske

+1 cho SRP. Bằng cách viết các hàm gắn kết, người ta có thể dễ dàng kết hợp chúng theo kiểu chức năng để đạt được kết quả phức tạp hơn. Cuối cùng, tốt hơn là một chức năng được tạo thành từ ba chức năng khác được dán lại với nhau hơn là có một chức năng duy nhất thực hiện ba chức năng riêng biệt, ngay cả khi có liên quan đến nhau.
Mario T. Lanza

Vâng, nhưng một trách nhiệm duy nhất là gì. Nó chỉ là một khái niệm được tạo ra trong đầu của bạn. Nếu bạn cần 400 dòng cho một trách nhiệm duy nhất, khái niệm về trách nhiệm duy nhất của bạn có lẽ khác biệt nhiều so với tôi
Xitcod13

9

Nó phụ thuộc , nghiêm túc, có thực sự không phải là một câu trả lời chắc chắn cho câu hỏi này bởi vì ngôn ngữ mà bạn đang làm việc với các vấn đề, năm đến mười lăm dòng đề cập trong câu trả lời này có thể làm việc cho C # hoặc Java, nhưng bằng các ngôn ngữ khác, nó không cung cấp cho bạn làm việc nhiều Tương tự, tùy thuộc vào tên miền bạn đang làm việc, bạn có thể thấy mình viết các giá trị cài đặt mã trong một cấu trúc dữ liệu lớn. Với một số cấu trúc dữ liệu, bạn có thể có hàng chục phần tử mà bạn cần đặt, bạn có nên tách mọi thứ ra để tách các chức năng chỉ vì chức năng của bạn đang chạy dài?

Như những người khác đã lưu ý, quy tắc tốt nhất là một hàm phải là một thực thể logic duy nhất xử lý một tác vụ. Nếu bạn cố gắng thực thi các quy tắc hà khắc nói rằng các hàm không thể dài hơn n dòng và bạn làm cho giá trị đó quá nhỏ, mã của bạn sẽ khó đọc hơn khi các nhà phát triển thử và sử dụng các thủ thuật ưa thích để vượt qua quy tắc. Tương tự như vậy, nếu bạn đặt nó quá cao, nó sẽ không thành vấn đề và có thể dẫn đến mã xấu mặc dù sự lười biếng. Đặt cược tốt nhất của bạn là chỉ cần tiến hành đánh giá mã để đảm bảo rằng các chức năng đang xử lý một nhiệm vụ duy nhất và để nó ở đó.


8

Tôi nghĩ một vấn đề ở đây là độ dài của hàm không nói gì về độ phức tạp của nó. LỘC (Dòng mã) là một công cụ xấu để đo lường bất cứ điều gì.

Một phương thức không nên quá phức tạp, nhưng có những kịch bản trong đó một phương thức dài có thể dễ dàng duy trì. Lưu ý rằng ví dụ sau không nói rằng nó không thể được chia thành các phương thức, chỉ là các phương thức sẽ không thay đổi khả năng bảo trì.

ví dụ, một trình xử lý cho dữ liệu đến có thể có một câu lệnh chuyển đổi lớn và sau đó là mã đơn giản cho mỗi trường hợp. Tôi có mã như vậy - quản lý dữ liệu đến từ nguồn cấp dữ liệu. 70 (!) Trình xử lý mã hóa số. Bây giờ, người ta sẽ nói "sử dụng hằng" - có, ngoại trừ API không cung cấp cho họ và tôi muốn ở gần "nguồn" ở đây. Phương pháp nào? Chắc chắn - thật đáng buồn khi tất cả chúng đều xử lý dữ liệu từ cùng 2 cấu trúc khổng lồ. Không có lợi trong việc tách chúng ra trừ khi có thể có nhiều phương thức hơn (khả năng đọc). Mã về bản chất không phức tạp - một chuyển đổi, tùy thuộc vào một lĩnh vực. Sau đó, mọi trường hợp có một khối phân tích x các yếu tố của dữ liệu và xuất bản chúng. Không có ác mộng bảo trì. Có một điều lặp lại "nếu điều kiện xác định liệu một trường có dữ liệu hay không (pField = pFields [x], nếu pField-> Isset () {blabla}) - tương tự khá nhiều cho mọi trường ..

Thay thế bằng một thói quen nhỏ hơn nhiều có chứa vòng lặp lồng nhau và rất nhiều câu lệnh chuyển đổi thực sự và một phương thức lớn có thể dễ dàng duy trì hơn một vòng lặp nhỏ hơn.

Vì vậy, xin lỗi, LỘC không phải là một phép đo tốt để bắt đầu. Nếu bất cứ điều gì, thì nên sử dụng điểm phức tạp / quyết định.


1
LỘC là một công cụ tốt để sử dụng cho một khu vực nơi họ cung cấp một biện pháp có liên quan - các dự án rất lớn, nơi chúng có thể được sử dụng để giúp đưa ra ước tính về thời gian dự án tương tự có thể hoàn thành. Ngoài ra, mọi người có xu hướng lo lắng về họ quá nhiều.
rjzii

Đúng. Nó không giống như LỘC không phụ thuộc vào cách tôi viết mã biểu cảm, trên các bản sửa đổi định dạng, v.v ... LỘC hoàn toàn không phù hợp và đôi khi sử dụng bất kỳ kinh nghiệm nào của MBA. Chỉ có. Bạn có thể tự đưa mình vào danh sách những người không hiểu tại sao LỘC là một phép đo tồi, nhưng rõ ràng điều đó sẽ không khiến bạn trông như một người biết lắng nghe.
TomTom

Vui lòng xem lại những gì tôi đã nói một lần nữa, tôi lưu ý rằng LỘC là một công cụ tốt chỉ dành cho một lĩnh vực đo lường và sử dụng (tức là các dự án cực kỳ lớn, nơi chúng có thể được sử dụng để ước tính). Bất cứ điều gì nhỏ hơn quy mô lớn và họ sử dụng hầu hết nếu không phải tất cả giá trị cho bất cứ điều gì ngoài âm thanh nhanh chóng trong cuộc họp để giữ cho mọi người hạnh phúc. Họ giống như cố gắng sử dụng năm ánh sáng để đo lường mức độ công bằng của quán cà phê từ văn phòng, chắc chắn bạn có thể làm điều đó, nhưng việc đo lường là vô ích. Nhưng khi bạn cần thảo luận về khoảng cách giữa các ngôi sao thì chúng hoạt động rất tốt.
rjzii

2
+1 một chức năng nên có tất cả mã cần thiết để thực hiện chức năng. Nó nên làm một điều và một điều duy nhất - nhưng nếu điều đó cần 1000 dòng mã thì cứ như vậy.
James Anderson

Tôi đã xử lý bằng văn bản cho dữ liệu ổ cắm đến và vâng, họ có thể yêu cầu một ngàn LỘC trở lên. Tuy nhiên, tôi có thể đếm bằng một tay số lần tôi cần để làm điều đó và không thể đếm số lần đó không phải là cách thích hợp để viết mã.

7

Tôi sẽ chỉ đưa vào một trích dẫn khác.

Các chương trình phải được viết để mọi người đọc và chỉ tình cờ để máy thực thi

- Harold Abelson

Rất có khả năng các chức năng tăng lên 100-200 tuân theo quy tắc này


1
Ngoại trừ khi chúng có chứa một công tắc.
Calmarius

1
hoặc xây dựng một đối tượng dựa trên kết quả của truy vấn cơ sở dữ liệu trả về hàng chục trường mỗi hàng trong tập kết quả ...
jwenting

Các kết quả cơ sở dữ liệu chắc chắn là một ngoại lệ có thể chấp nhận - cộng với chúng thường là các câu lệnh "ngu ngốc" cư trú trong một số trường hợp của một lớp (hoặc bất cứ điều gì), thay vì logic hơn là cần phải tuân theo.
MetalMikester

6

Tôi đã ở trong cây vợt điên rồ này, bằng cách này hay cách khác, kể từ năm 1970.

Trong tất cả thời gian đó, với hai ngoại lệ mà tôi sẽ gặp phải trong một khoảnh khắc, tôi KHÔNG BAO GIỜ thấy một "thói quen" được thiết kế tốt (phương thức, thủ tục, chức năng, chương trình con, bất cứ điều gì) CẦN phải nhiều hơn một trang in ( dài khoảng 60 dòng). Phần lớn trong số chúng khá ngắn, theo thứ tự 10-20 dòng.

Tuy nhiên, tôi đã thấy RẤT NHIỀU mã "dòng ý thức", được viết bởi những người dường như chưa bao giờ nghe nói về mô đun hóa.

Hai trường hợp ngoại lệ là rất nhiều trường hợp đặc biệt. Một thực sự là một lớp các trường hợp ngoại lệ, mà tôi gộp lại: automata trạng thái hữu hạn lớn, được triển khai như các câu lệnh chuyển đổi xấu xí lớn, thường là do không có cách nào sạch hơn để thực hiện chúng. Những thứ này thường xuất hiện trong thiết bị kiểm tra tự động, phân tích nhật ký dữ liệu từ thiết bị được kiểm tra.

Cái còn lại là thói quen ngư lôi photon từ trò chơi STARTRK Matuszek-Reynolds-McGehearty-Cohen, được viết trong CDC 6600 FORTRAN IV. Nó phải phân tích dòng lệnh, sau đó mô phỏng chuyến bay của từng ngư lôi, với sự nhiễu loạn, kiểm tra sự tương tác giữa ngư lôi và từng loại nó có thể đánh trúng, và bằng cách mô phỏng đệ quy để thực hiện kết nối 8 chiều trên các chuỗi novae từ ngư lôi một ngôi sao bên cạnh những ngôi sao khác.


2
+1 cho sự rung cảm "rời khỏi bãi cỏ của tôi" tôi nhận được từ câu trả lời này. Ngoài ra, từ kinh nghiệm cá nhân từ trước khi các ngôn ngữ OOP được phổ biến rộng rãi.

Nó không quá "rời khỏi bãi cỏ của tôi" như một quan sát mà tôi đã thấy RẤT NHIỀU mã tào lao trong những năm qua, và dường như nó đang bị WORSE.
John R. Strohm

Sếp của tôi có thói quen viết các phương thức dài hàng trăm dòng, thường có nhiều cấp độ if lồng nhau. Anh ta cũng sử dụng các lớp một phần (.NET) để "chia" một lớp thành nhiều tệp để anh ta có thể tuyên bố rằng anh ta giữ chúng ngắn. Đó chỉ là hai điều tôi phải giải quyết. Đã làm điều này trong khoảng 25 năm và tôi có thể xác nhận rằng mọi thứ đang trở nên tồi tệ hơn. Và bây giờ thời gian để tôi quay trở lại vào mớ hỗn độn đó.
MetalMikester

5

Nếu tôi tìm thấy phương pháp dài, tôi có thể đặt cược phương pháp này không được kiểm tra đơn vị đúng cách hoặc hầu hết thời gian nó không kiểm tra đơn vị. Nếu bạn bắt đầu thực hiện TDD, bạn sẽ không bao giờ xây dựng các phương thức 100 dòng với 25 trách nhiệm khác nhau và 5 vòng lặp lồng nhau. Các xét nghiệm bắt buộc bạn phải liên tục cấu trúc lại mớ hỗn độn của mình và viết mã sạch của chú Bob.


2

Không có quy tắc tuyệt đối về độ dài của phương thức, nhưng các quy tắc sau đây rất hữu ích:

  1. Mục đích chính của chức năng là tìm giá trị trả về. Không có lý do khác cho sự tồn tại của nó. Khi lý do đó đã được điền đầy đủ, không có mã nào khác được chèn vào nó. Điều này nhất thiết phải giữ chức năng nhỏ. Gọi các chức năng khác chỉ nên được thực hiện nếu nó làm cho việc tìm giá trị trả về dễ dàng hơn.
  2. Mặt khác, giao diện nên nhỏ. Điều này có nghĩa là bạn có số lượng lớn các lớp hoặc bạn có các hàm lớn - một trong hai lớp sẽ xảy ra khi bạn bắt đầu có đủ mã để làm bất cứ điều gì quan trọng. Các chương trình lớn có thể có cả hai.

1
Điều gì về tác dụng phụ - ghi vào một tập tin, đặt lại trạng thái, vv?
Vorac

2

Các tác giả có cùng ý nghĩa với "chức năng" và "thói quen" không? Thông thường khi tôi nói "hàm" Tôi có nghĩa là một chương trình con / hoạt động trả về một giá trị và "thủ tục" cho một lệnh không (và cuộc gọi của ai trở thành một câu lệnh đơn). Đây không phải là một sự phân biệt phổ biến trong suốt SE trong thế giới thực nhưng tôi đã thấy nó trong các văn bản người dùng.

Dù bằng cách nào, không có câu trả lời đúng cho điều này. Ưu tiên cho cái này hay cái khác (nếu có một ưu tiên nào đó) là điều tôi mong đợi sẽ rất khác nhau giữa các ngôn ngữ, dự án và tổ chức; giống như nó là với tất cả các quy ước mã.

Một điều tôi muốn nói thêm là toàn bộ "các hoạt động dài không dễ bị lỗi hơn các hoạt động ngắn" là không đúng hoàn toàn. Ngoài thực tế là nhiều mã tương đương với không gian lỗi tiềm năng hơn, rõ ràng là việc phá mã thành các phân đoạn sẽ làm cho các lỗi vừa dễ tránh vừa dễ xác định hơn. Nếu không, sẽ không có lý do gì để chia mã thành từng mảnh, lưu lại sự lặp lại. Nhưng điều này có lẽ chỉ đúng nếu các phân đoạn nói được ghi lại đủ tốt để bạn có thể xác định kết quả của một cuộc gọi hoạt động mà không cần đọc qua hoặc truy tìm mã thực tế (thiết kế theo hợp đồng dựa trên thông số kỹ thuật thay vì phụ thuộc cụ thể giữa các khu vực của mã).

Ngoài ra, nếu bạn muốn các hoạt động dài hơn hoạt động tốt, bạn có thể muốn áp dụng các quy ước mã chặt chẽ hơn để hỗ trợ chúng. Việc đưa ra một tuyên bố trả lại ở giữa một hoạt động có thể tốt cho một hoạt động ngắn, nhưng trong các hoạt động dài hơn, điều này có thể tạo ra một phần lớn mã có điều kiện nhưng rõ ràng không có điều kiện trên một lần đọc nhanh (chỉ cho một ví dụ).

Vì vậy, tôi sẽ nghĩ rằng phong cách nào ít có khả năng là cơn ác mộng đầy lỗi sẽ phụ thuộc phần lớn vào những quy ước mà bạn tuân thủ trong phần còn lại của mã. :)


1

IMHO, bạn không cần phải sử dụng thanh cuộn để đọc chức năng của mình. Ngay khi bạn cần di chuyển thanh cuộn, phải mất thêm một ít thời gian để hiểu chức năng hoạt động như thế nào.

Theo đó, nó phụ thuộc vào môi trường lập trình thông thường của công việc nhóm của bạn (độ phân giải màn hình, trình chỉnh sửa, kích thước phông chữ, v.v ...). Trong những năm 80, nó là 25 dòng và 80 cột. Bây giờ, trên trình chỉnh sửa của tôi, tôi hiển thị gần 50 dòng. Số cột tôi hiển thị không thay đổi kể từ khi tôi chia đôi màn hình của mình để hiển thị hai tệp.

Tóm lại, nó phụ thuộc vào việc thiết lập đồng nghiệp của bạn.


2
Không phải là 24 dòng thời gian đó sao? Tôi đang nghĩ về 3270 hoặc 9750 thiết bị đầu cuối, trong đó số 25 là dòng trạng thái. Và các mô phỏng thiết bị đầu cuối theo sau này.
ott--

một số hệ thống / biên tập viên đã có 40 hoặc 50 dòng từ đầu. Ngày nay, 150 dòng không phải là hiếm và 200+ là có thể thực hiện được, vì vậy đó không thực sự là một số liệu tốt.
Móż

Tôi sử dụng màn hình của mình theo hướng dọc, tôi có thể thấy 200 dòng mã cùng một lúc.
Calmarius

và nếu tôi không sử dụng bất kỳ ngắt dòng nào để ngắt dòng của mình, tôi có thể mã hóa phương thức 5000 dòng trong một dòng duy nhất ...
jwenting

1

Tôi nghĩ rằng câu trả lời của TomTom gần với cách tôi cảm nhận về nó.

Càng ngày tôi càng thấy mình phức tạp theo chu kỳ hơn là các dòng.

Tôi thường nhắm đến không quá một cấu trúc điều khiển cho mỗi phương thức, ngoại trừ nhiều vòng lặp cần có để xử lý một mảng nhiều chiều.

Đôi khi tôi thấy mình đặt ifs một dòng trong các trường hợp chuyển đổi bởi vì một số lý do, đây có thể là những trường hợp tách nó ra gây cản trở hơn là giúp đỡ.

Lưu ý rằng tôi không tính logic bảo vệ chống lại giới hạn này.


Độ phức tạp theo chu kỳ đã được chứng minh, với số lượng lớn mã sản xuất thực, có RẤT tương quan mạnh với SLOC thô, làm cho việc tính toán độ phức tạp chu kỳ trở thành một sự lãng phí toàn bộ thời gian, năng lượng và chu kỳ đồng hồ.
John R. Strohm

@ JohnR.Strohm Tôi đang nói về mỗi phương pháp, không phải tổng thể. Chắc chắn, trong bức tranh lớn, nó có mối tương quan cao - câu hỏi là làm thế nào để chia mã đó thành các phương thức. 10 phương thức của 100 dòng hoặc 100 phương thức của 10 dòng vẫn sẽ có cùng SLOC và độ phức tạp, nhưng trước đây sẽ khó hơn rất nhiều để làm việc.
Loren Pechtel

Tôi cũng vậy. Nghiên cứu tương quan đã xem xét RẤT NHIỀU mã và RẤT NHIỀU thói quen. (Đó là một trong những kho lưu trữ công cộng lớn.)
John R. Strohm

-3

Trong OOP tất cả các đối tượng và có các tính năng sau:

  1. Đa hình
  2. Trừu tượng
  3. Di sản

Khi bạn tuân thủ các quy tắc này thì các phương thức của bạn thường nhỏ nhưng không tồn tại bất kỳ quy tắc nào cho quy tắc nhỏ hoặc rất nhỏ (ví dụ 2-3 dòng). Lợi ích của phương thức nhỏ (đơn vị nhỏ, ví dụ phương thức hoặc hàm) là:

  1. dễ đọc hơn
  2. duy trì tốt hơn
  3. sửa lỗi tốt hơn
  4. thay đổi tốt hơn
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.