Khi nào một tên phương thức Java quá dài? [đóng cửa]


173

Trong những tuần trước tôi đã thấy một số kẻ sử dụng tên rất dài cho Phương thức hoặc Lớp (50 ký tự), điều này thường là tiền đề để cải thiện khả năng đọc, ý kiến ​​của tôi là một tên dài như thế này là một chỉ báo cho thấy chúng ta cố gắng làm nhiều hoặc quá nhiều trong một lớp phương thức nếu chúng ta cần một cái tên dài như vậy, tuy nhiên tôi muốn biết các bạn nghĩ gì về nó.

Một ví dụ là:

getNumberOfSkinCareEligibleItemsWithinTransaction

19
CÓ, đó là "mùi mã" ... c2.com/cgi/wiki?LongMethodSmell
Dan Rosenstark

23
Khi nó dài> 666 ký tự thì bạn biết bạn có vấn đề.
Thomas Eding

8
@yar trong ví dụ của bạn, ngược lại với "Phương pháp dài" là "Phương pháp ngắn" được coi là một điều tốt. Vì vậy, rõ ràng là không đề cập đến tên phương thức; nó đề cập đến các dòng mã (hoặc tương tự như vậy). ví dụ, f()là một hàm rất ngắn, nhưng nó chắc chắn không phải là thực hành tốt ... và một cái gì đó bạn nên nói với một số nhà toán học lập trình ngoài đó :)
sfussalanger

3
@sfussalanger, đúng vậy. Nhưng tôi đang đặt cược vào mối tương quan giữa độ dài tên phương thức và độ dài phương thức. f()có thể không phải là một chức năng tuyệt vời, nhưng $()anh chàng đó giống như một ngôi sao nhạc rock trong thế giới phương thức Javascript.
Dan Rosenstark

7
@yar, liên kết bạn đã đưa ra đề cập đến độ dài của phương thức trong các dòng, không phải độ dài của tên phương thức .
Thorbjørn Ravn Andersen

Câu trả lời:


398

Một tên trong Java, hoặc bất kỳ ngôn ngữ nào khác, quá dài khi tồn tại một tên ngắn hơn truyền tải hành vi của phương thức như nhau.


65
Toán học thanh lịch.
Ricket

304
Vì vậy, ví dụ, boolean doesShorterNameExistThatEquallyConvaysTheBehaviorOfTheMethod(String s)nên được tái cấu trúc boolean isTooLong(String s).
z5h

6
Tôi không hoàn toàn đồng ý, vì bạn không chỉ muốn truyền đạt hành vi mà còn giữ nguyên quy ước của dự án và ngôn ngữ. Vì vậy, trong Python bạn có thể nói eligible_items_cntnhưng trong Java bạn thường nói getEligibleItemsCount.
flybywire

17
@flybywire: Bất kỳ quy ước nào khiến bạn viết tên quá dài đều có lợi ích đáng ngờ.
MAK

20
@MAK @ S.Lott thì sao getLength()so với length()? Tôi thực sự thích nhìn vào tự động hoàn thành sau khi gõ 'get' hoặc 'set' - vì vậy tôi thích sự thèm muốn hơn sự đồng nhất trong trường hợp này.
sfussalanger

202

Một số kỹ thuật để giảm độ dài của tên phương thức:

  1. Nếu toàn bộ chương trình, hoặc lớp học hoặc mô-đun của bạn là về 'các mặt hàng chăm sóc da', bạn có thể bỏ chăm sóc da. Ví dụ, nếu lớp của bạn được gọi SkinCareUtils, điều đó đưa bạn đếngetNumberOfEligibleItemsWithinTransaction

  2. Bạn có thể thay đổi trong phạm vi để ,getNumberOfEligibleItemsInTransaction

  3. Bạn có thể thay đổi Giao dịch thành Tx, điều này đưa bạn đến getNumberOfEligibleItemsInTx.

  4. Hoặc nếu phương thức chấp nhận một loại param, Transactionbạn có thể loại bỏ InTx hoàn toàn:getNumberOfEligibleItems

  5. Bạn thay đổi numberOf theo số lượng: getEligibleItemsCount

Bây giờ điều đó là rất hợp lý. Và nó ngắn hơn 60%.


11
ngoài ra, 5) sẽ đặt getEligibleItems()getEligibleItemsCount()cạnh nhau trong các danh sách theo thứ tự bảng chữ cái (ví dụ: tự động hoàn thành hoặc javadoc)
sfussalanger

4
Và như thường lệ, tên ngắn hơn phù hợp với quy tắc haiku.
sal

2
@mercator Sử dụng một quy ước tiêu chuẩn như getElitableItems trên CountElitableItems làm giảm cơ hội cho sự mơ hồ trong tuyên bố. Càng ít mơ hồ về những gì phương pháp được cho là làm tăng khả năng đọc. Không cần nhìn sâu hơn vào phương thức, một phương thức "đếm" ít rõ ràng hơn phương thức "đạt được" thực hiện trong thời gian dài.
Hóa đơn

53
Tôi không thích abbr như Tx, Cnt, grph, và vân vân ... (btw, Txlà viết tắt của "truyền" hoặc "phát")
Meinersbur

14
Vâng, tôi đã đồng ý với bạn cho đến khi bạn quyết định sử dụng "Tx".
Ponkadoodle

183

Chỉ cần thay đổi, một câu trả lời không chủ quan: 65536 ký tự.

A.java:1: Đại diện UTF8 cho chuỗi "xxxxxxxxxxxxxxxxxxxx ..." quá dài cho nhóm liên tục

;-)


4
vâng, nó quá dài khi JVM không thể xử lý nó không mo :)
Anurag

35
1 cho THE câu trả lời theo nghĩa đen.
sal

37
Về mặt kỹ thuật, đặc tả ngôn ngữ Java không có giới hạn trên cho chiều dài định danh. Đây là một hạn chế trong việc thực hiện JVM của bạn. Chúc mừng!
uckelman

13
Trình biên dịch của Sun dường như không phù hợp với thông số kỹ thuật. java.sun.com/docs/books/jls/third_edition/html/lexical.html#3.8 nói: "Mã định danh là một chuỗi có độ dài không giới hạn ..."
Michael Myers

6
Thông số JVM không có giới hạn trên, như thông báo lỗi chỉ ra. Đại diện nhóm không đổi của utf8 được giới hạn ở 2 ^ 16 byte được chỉ định ở đây . Tên lớp và tên phương thức phải được lưu trữ dưới dạng utf8 trong nhóm không đổi.
thejoshwolfe

42

Tôi đồng ý với mọi người: tên phương thức không nên quá dài. Tôi muốn thêm một ngoại lệ:

Tuy nhiên, tên của các phương thức kiểm tra JUnit có thể dài và phải giống với các câu.

Tại sao?

  • Bởi vì chúng không được gọi trong mã khác.
  • Bởi vì chúng được sử dụng làm tên thử nghiệm.
  • Bởi vì sau đó chúng có thể được viết dưới dạng câu mô tả các yêu cầu. (Ví dụ: sử dụng AgileDox )

Thí dụ:

    @Test
    public void testDialogClosesDownWhenTheRedButtonIsPressedTwice() {
        ...
    }

Xem " Thiết kế hướng hành vi " để biết thêm thông tin về ý tưởng này.


5
+1 Tôi đồng ý với nó và đó cũng là những gì tôi đang làm, mặc dù các phương pháp JUnit 4 không bắt buộc phải bắt đầu testnữa, điều này cũng mở ra khả năng sử dụng should: chẳng hạn như dialogShouldCloseWhenTheRedButtonIsPressedTwice(). Hoặc bạn có thể gọi lớp kiểm tra DialogShouldvà sau đó là phương thức closeWhenTheRedButtonIsPressedTwice(), để đọc chúng cùng nhau : DialogShould.closeWhenTheRedButtonIsPressedTwice().
stivlo

Trong khi tôi đồng ý, tôi cũng đề nghị rằng một câu quá dài có thể gợi ý một bài kiểm tra đang làm quá nhiều!
Brian Agnew

17

Bối cảnh "... InsideTransaction" nên rõ ràng. Đó là những gì hướng đối tượng là tất cả về.

Phương thức này là một phần của một lớp. Nếu lớp không có nghĩa là "Giao dịch" - và nếu nó không giúp bạn khỏi phải nói "InsideTransaction" mọi lúc, thì bạn đã gặp vấn đề.


2
Cũng có thể mất một số loại tham số giao dịch
willcodejavaforfood

3
Như bạn có thể nói từ câu trả lời đạt điểm cao nhất ở trên, hãy tìm sự đơn giản ở vùng hẻo lánh thay vì lời khuyên OO. +1
Dan Rosenstark

@yar Người không bao giờ sai.
RèmDog

12

Tôi có xu hướng sử dụng quy tắc haiku cho tên:

 Seven syllable class names 
 five for variables
 seven for method and other names

Đây là quy tắc của ngón tay cái cho tên tối đa. Tôi chỉ vi phạm điều này khi nó cải thiện khả năng đọc. Một cái gì đó như recalculateMortthingInterest (currentRate, quote Set ...) tốt hơn recalculateMortidorInterestRate hoặc recalculateMortthingInterestRateFromset vì thực tế là nó liên quan đến tỷ lệ và một bộ trích dẫn nên khá rõ ràng từ các tài liệu được nhúng như javadoc.

LƯU Ý: Không phải là haiku thực sự, vì nó là 7-5-7 thay vì 5-7-5. Nhưng tôi vẫn thích gọi nó là haiku.


13
Các lớp học nhận được bảy, các biến số ít hơn năm, bảy cho phần còn lại
James

8
"Biến nhiều nhất là năm" (ít hơn năm là không chính xác)
Jason S

Tên nhỏ hơn có thể dẫn đến khả năng đọc mã thấp hơn.
Deniss M.

10

Java có văn hóa khuyến khích những cái tên dài, có lẽ vì các IDE đi kèm với khả năng tự động hoàn thành tốt.

Trang web này nói rằng tên lớp dài nhất trong JRE InternalFrameInternalFrameTitlePaneInternalFrameTitlePaneMaximizeButtonWindowNotFocusedStatelà 92 ký tự dài.

Đối với tên phương thức dài nhất tôi đã tìm thấy cái này supportsDataDefinitionAndDataManipulationTransactions, có 52 ký tự.


20
Có vẻ như lớp học đó được đặt tên bởi những người đặt tên được thuê bởi Bộ phận dư thừa để đặt tên cho Bộ phận của Cục Dự phòng.
Michael Madsen

1
@MichaelMadsen: Nó thực sự dư thừa, hay nó mô tả một khung được lồng trong một khung khác?
endolith

PEP-8 muốn một từ có tên lớp đó.
Mateen Ulhaq

9

Không bao giờ sử dụng một từ dài khi một từ nhỏ sẽ làm.

Tôi không nghĩ rằng luận điểm của bạn về "độ dài của tên phương thức tỷ lệ thuận với độ dài của phương thức" thực sự giữ nước.

Lấy ví dụ bạn đưa ra: "getNumberOfSkinCareElTHERItemsWithinTransaction". Nghe có vẻ như tôi chỉ làm một việc: nó đếm số lượng vật phẩm trong một giao dịch thuộc một danh mục nhất định. Tất nhiên tôi không thể phán đoán mà không xem mã thực tế cho phương thức, nhưng đó có vẻ là một phương pháp tốt đối với tôi.

Mặt khác, tôi đã thấy rất nhiều phương thức với các tên rất ngắn gọn và súc tích, có tác dụng với nhiều công việc, như "processSale" hay "doStuff" phổ biến.

Tôi nghĩ rằng sẽ rất khó để đưa ra một quy tắc khó và nhanh về độ dài tên phương thức, nhưng mục tiêu phải là: đủ dài để truyền đạt những gì hàm làm, đủ ngắn để có thể đọc được. Trong ví dụ này, tôi nghĩ rằng "getSkinCareCount" có lẽ đã đủ. Câu hỏi là những gì bạn cần phân biệt. Nếu bạn có một chức năng đếm các mặt hàng đủ điều kiện chăm sóc da trong các giao dịch và một chức năng khác tính các mặt hàng đủ điều kiện chăm sóc da trong một thứ khác, thì "bên trong giao dịch" sẽ tăng thêm giá trị. Nhưng nếu nó không có nghĩa gì để nói về những mặt hàng như vậy bên ngoài một giao dịch, thì sẽ không có điểm nào làm lộn xộn tên với thông tin thừa thãi như vậy.

Hai, tôi nghĩ thật phi thực tế khi cho rằng một tên có độ dài có thể quản lý được sẽ cho bạn biết chính xác chức năng này làm gì trong tất cả các trường hợp ngoại trừ các trường hợp tầm thường nhất. Một mục tiêu thực tế là tạo ra một cái tên mang đến cho người đọc một manh mối, và điều đó có thể được ghi nhớ sau này. Giống như, nếu tôi đang cố gắng tìm mã tính toán lượng phản vật chất chúng ta cần tiêu thụ để đạt tốc độ cong vênh, nếu tôi nhìn vào tên hàm và thấy "calibrateTransporter", "firePhasers" và "calcAntimatterBurn", thì rõ ràng rằng hai cái đầu không phải nó nhưng cái thứ ba có thể là. Nếu tôi kiểm tra và thấy rằng đó thực sự là người tôi đang tìm kiếm, sẽ dễ dàng nhớ rằng khi tôi trở lại vào ngày mai để giải quyết vấn đề này thêm một lần nữa. Thế là đủ tốt rồi.

Ba, tên dài tương tự nhau khó hiểu hơn tên ngắn. Nếu tôi có hai chức năng gọi là "calcSalesmanPay" và "calcGeekPay", tôi có thể đoán được đó là một cái nhìn nhanh chóng. Nhưng nếu chúng được gọi là "notifyMonthlyCheckAmountForSalesmanForExportToAccountingSystemAndReconcestion" và "notifyMonthlyCheckAmountForProgrammersForExportToAccountingSystemAndReconcestion" thì tôi phải tìm tên nào. Các thông tin bổ sung trong tên có lẽ là phản tác dụng trong những trường hợp như vậy. Nó biến suy nghĩ nửa giây thành suy nghĩ 30 giây.


+1 cho câu trả lời nghèo nàn này đã phải chịu đựng.
Dan Rosenstark

7

Thiết kế giao diện của bạn theo cách bạn muốn và làm cho việc thực hiện khớp.

Ví dụ, có lẽ tôi sẽ viết nó như là

getTransaction().getItems(SKIN_CARE).getEligible().size()

hoặc với các luồng Java 8:

getTransaction().getItems().stream()
    .filter(item -> item.getType() == SKIN_CARE)
    .filter(item -> item.isEligible())
    .count();

6

Quy tắc của tôi là như sau: nếu một cái tên quá dài đến nỗi nó phải xuất hiện trên một dòng của chính nó, thì nó quá dài. (Trong thực tế, điều này có nghĩa là tôi hiếm khi trên 20 ký tự.)

Điều này dựa trên nghiên cứu cho thấy số lượng dòng mã dọc có thể nhìn thấy tương quan dương với tốc độ / hiệu quả mã hóa. Nếu tên lớp / phương thức bắt đầu làm tổn thương đáng kể điều đó, thì chúng quá dài.

Thêm một nhận xét trong đó phương thức / lớp được khai báo và để IDE đưa bạn đến đó nếu bạn muốn mô tả dài về mục đích của nó.


Tôi thích các quy tắc như thế này. Miễn là bạn nhớ rằng bạn / nhóm của bạn đã tạo ra chúng một cách ngẫu nhiên, tất cả đều tốt. Mặt khác, tôi không thể nâng cao điều này bởi vì "nghiên cứu cho thấy" thực sự sẽ cần một liên kết đến nghiên cứu đó, hoặc một cái gì đó về nó ...
Dan Rosenstark

5

Độ dài của phương thức có lẽ là một chỉ báo tốt hơn về việc liệu nó có làm quá nhiều hay không và thậm chí điều đó chỉ mang đến cho bạn một ý tưởng sơ bộ. Bạn nên cố gắng cho sự đồng nhất, nhưng mô tả là quan trọng hơn. Nếu bạn không thể truyền đạt ý nghĩa tương tự trong một tên ngắn hơn, thì tên đó có thể ổn.


3

Khi bạn định viết một tên phương thức vào lần tới, hãy nghĩ đoạn trích dưới đây

"The man who is going to maintain your code is a phyco who knows where you stay"

13
Điều tốt là anh ấy chỉ là rong biển chứ không phải là một 'kẻ tâm thần'
StingyJack

2

Tên phương thức đó chắc chắn là quá dài. Tâm trí của tôi có xu hướng đi lang thang khi tôi đang đọc tên phương thức có kích thước như vậy. Nó giống như đọc một câu không có khoảng trắng.

Cá nhân, tôi thích càng ít từ trong phương pháp càng tốt. Bạn được giúp đỡ nếu gói và tên lớp có thể truyền đạt ý nghĩa. Nếu trách nhiệm của lớp rất ngắn gọn , thì không cần phải có một tên phương thức khổng lồ. Tôi tò mò tại sao "InsideTransaction" ở đó.

"getNumberOfSkinCareEllableItemsWithinTransaction" có thể trở thành:

com.mycompany.app.product.SkinCareQuery.getNumEl đủItems ();

Sau đó, khi sử dụng, phương thức có thể trông giống như "query.getNumElTHERItems ()"


2

Tên biến quá dài khi tên ngắn hơn sẽ cho phép khả năng đọc mã tốt hơn trên toàn bộ chương trình hoặc các phần quan trọng của chương trình.

Nếu một tên dài hơn cho phép bạn truyền đạt nhiều thông tin hơn về một giá trị. Tuy nhiên, nếu một tên quá dài, nó sẽ làm lộn xộn mã và giảm khả năng hiểu phần còn lại của mã. Điều này thường xảy ra bằng cách gây ra các dòng kết thúc và đẩy các dòng mã khác ra khỏi trang.

Bí quyết là xác định cái nào sẽ cung cấp khả năng đọc tốt hơn. Nếu biến được sử dụng thường xuyên hoặc nhiều lần trong một khoảng trống ngắn, có thể tốt hơn là đặt tên ngắn và sử dụng nhận xét làm rõ. Người đọc có thể tham khảo lại bình luận dễ dàng. Nếu biến được sử dụng thường xuyên trong suốt chương trình, thường là một tham số hoặc trong các hoạt động phức tạp khác, tốt nhất nên cắt bớt tên hoặc sử dụng các từ viết tắt như một lời nhắc nhở cho người đọc. Họ luôn có thể tham chiếu một nhận xét bằng cách khai báo biến nếu họ quên ý nghĩa.

Đây không phải là một sự đánh đổi dễ dàng, vì bạn phải xem xét những gì người đọc mã có thể đang cố gắng hiểu và cũng tính đến cách mã sẽ thay đổi và phát triển theo thời gian. Đó là lý do tại sao việc đặt tên là khó khăn.

Khả năng đọc là lý do tại sao có thể chấp nhận sử dụng i làm bộ đếm vòng thay vì DescriptiveLoopC gặpName. Vì đây là cách sử dụng phổ biến nhất cho một biến, bạn có thể dành ít không gian màn hình nhất để giải thích lý do tại sao nó tồn tại. Tên dài hơn sẽ lãng phí thời gian bằng cách làm cho khó hiểu hơn về cách bạn đang kiểm tra điều kiện vòng lặp hoặc lập chỉ mục vào một mảng.

Ở đầu kia của phổ, nếu một hàm hoặc biến hiếm khi được sử dụng như trong một hoạt động phức tạp, chẳng hạn như được chuyển đến một lệnh gọi hàm đa tham số, bạn có thể đặt cho nó một tên mô tả quá mức.


1

Như với bất kỳ ngôn ngữ nào khác: khi nó không còn mô tả hành động đơn lẻ thì chức năng thực hiện.


1

Tôi muốn nói sử dụng kết hợp các câu trả lời tốt và hợp lý.

Mô tả đầy đủ, rõ ràng và dễ đọc những gì phương pháp làm.

Nếu tên phương thức có vẻ quá dài - hãy cấu trúc lại phương thức để thực hiện ít hơn.


1

Quá dài khi tên của phương thức kết thúc trên một dòng khác và lệnh gọi phương thức là thứ duy nhất trên dòng và bắt đầu khá gần với lề. Bạn phải tính đến kích thước trung bình của màn hình của những người sẽ sử dụng nó.

Nhưng! Nếu tên có vẻ quá dài thì có lẽ nó quá dài. Cách để giải quyết vấn đề là viết mã của bạn theo cách bạn đang ở trong một bối cảnh và tên ngắn nhưng được sao chép trong các ngữ cảnh khác. Điều này giống như khi bạn có thể nói "cô ấy" hoặc "anh ấy" bằng tiếng Anh thay vì tên đầy đủ của ai đó.


1

Nó quá dài khi nó quá dài dòng giải thích điều đó là gì.

Ví dụ, những tên này là tương đương về chức năng.

trong Java: java.sql.SQLIntegrityConstraintViolationException

trong Python / Django: django.db.IntegrityError

Hãy tự hỏi, trong gói SQL / db, bạn có thể gặp thêm bao nhiêu loại lỗi toàn vẹn? ;) Do đó db.IntegrityErrorlà đủ.


Bạn luôn có thể tranh luận theo cách khác. Khi nó được giải thích một cách rõ ràng những gì về vấn đề này thì rõ ràng phương thức này làm gì khác, nó có thể gây nhầm lẫn và có thể gây ra việc sử dụng sai phương pháp.
Jonas Geiregat

0

Tên định danh quá dài khi vượt quá độ dài mà trình biên dịch Java của bạn có thể xử lý.


3
Gì?! Tôi không thấy lý do tại sao tôi bị hạ thấp vì điều này. Câu hỏi không yêu cầu một điều kiện cần thiết, chỉ cần một câu hỏi đủ!
uckelman

0

Có hai cách hoặc quan điểm ở đây: Một là nó thực sự không quan trọng tên của phương thức là bao lâu, miễn là mô tả càng tốt để mô tả phương thức đang làm gì (quy tắc cơ bản tốt nhất của Java). Mặt khác, tôi đồng ý với bài flybywire. Chúng ta nên sử dụng trí thông minh của mình để cố gắng giảm càng nhiều càng tốt tên phương thức, nhưng không làm giảm tính mô tả. Mô tả là quan trọng hơn :)


0

Một cái tên quá dài nếu nó:

  • Mất hơn 1 giây để đọc
  • Chiếm nhiều RAM hơn mức bạn phân bổ cho JVM của bạn
  • Là một cái gì đó vô lý được đặt tên
  • Nếu một tên ngắn hơn có ý nghĩa hoàn hảo
  • Nếu nó kết thúc tốt đẹp trong IDE của bạn

Thành thật mà nói, tên chỉ cần truyền đạt mục đích của nó cho các Nhà phát triển sẽ sử dụng nó như một phương thức API công khai hoặc phải duy trì mã khi bạn rời đi. Chỉ cần nhớ KISS (giữ cho nó đơn giản ngu ngốc)

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.