Được coi là thực hành kém để bao gồm một số lỗi trong tên phương thức cho một cách giải quyết tạm thời?


27

Đồng nghiệp của tôi, một người đàn ông cao cấp đang chặn tôi trong bài đánh giá mã vì anh ta muốn tôi đặt tên cho một phương thức 'PerformanceSqlClient216147Workaround' vì đó là một cách giải quyết cho một số khiếm khuyết ###. Bây giờ, đề xuất tên phương thức của tôi là một cái gì đó giống như PerformanceRightExpressionCast có xu hướng mô tả những gì phương thức thực sự làm. Lập luận của ông đi theo hướng: "Chà phương pháp này chỉ được sử dụng như một cách giải quyết cho trường hợp này, và không ở đâu khác."

Sẽ bao gồm số lỗi bên trong tên phương thức cho một cách giải quyết tạm thời được coi là thực hành xấu?


Chỉ cần làm rõ: lỗi ### nằm trong một thành phần bên ngoài có tên là SqlClient, nó đã được đệ trình vào năm 2008, rất có thể nó sẽ không được sửa chữa sớm và nó nằm ngoài khả năng của chúng tôi, vì vậy phương pháp này là một phần của thiết kế để " giải quyết vấn đề đó ...
Bojan

2
Nó vẫn đọc như một lời ca ngợi nên tôi đã tập trung lại và đặt lại câu hỏi cho cốt lõi của những gì bạn đang hỏi. Tôi cảm thấy rằng đó là một câu hỏi công bằng bây giờ. Những câu hỏi như "Cấp trên của tôi đã làm X, anh ấy rất sai ... ĐÚNG GUYS?" thường được đóng là Không xây dựng.
maple_shaft

41
Giả sử cách giải quyết tạm thời sẽ trở thành vĩnh viễn. Họ luôn làm thế.
dùng16764

2
@maple_shaft - chỉnh sửa lưu tuyệt vời cho câu hỏi.

2
Lỗi # dành cho nhận xét và kiểm soát phiên bản ghi chú cam kết, không phải tên phương thức. Đồng nghiệp của bạn nên được tát.
Erik Reppen

Câu trả lời:


58

Tôi sẽ không đặt tên phương thức như đồng nghiệp của bạn đề xuất. Tên phương thức nên chỉ ra phương thức nào. Một cái tên như PerformSqlClient216147Workaroundkhông chỉ ra những gì nó làm. Nếu bất cứ điều gì, sử dụng các ý kiến ​​mô tả phương pháp để đề cập rằng đó là một cách giải quyết. Điều này có thể trông giống như sau:

/**
 * Cast given right-hand SQL expression.
 *
 * Note: This is a workaround for an SQL client defect (#216147).
 */
public void CastRightExpression(SqlExpression rightExpression)
{
    ...
}

Tôi đồng ý với MainMa rằng các số lỗi / lỗi không nên xuất hiện trong chính mã nguồn mà thay vào đó là các bình luận kiểm soát nguồn vì đây là siêu dữ liệu, nhưng sẽ không tệ nếu chúng xuất hiện trong các nhận xét về mã nguồn. Số lỗi / lỗi không bao giờ được sử dụng trong tên của các phương thức.


5
Có một liên kết http trực tiếp đến lỗi trong bình luận tài liệu sẽ là một ý tưởng tốt. Bạn cũng có thể xác định các chú thích của riêng mình@Workaround(216147)
Sulthan

2
hoặc @warning This is a temporary hack to...hoặcTODO: fix for ...
Bовић

1
@Sulthan - Chắc chắn ... Cho phép liên kết đến cơ sở dữ liệu khiếm khuyết có thể không tồn tại trong một vài năm. Mô tả lỗi, đặt lỗi # (và ngày), ghi lại cách khắc phục nhưng liên kết đến các công cụ nội bộ có thể thay đổi có vẻ như là một ý tưởng tồi.
Ramhound

4
@Ramhound Bạn nên xem xét cơ sở dữ liệu khiếm khuyết của mình và thay đổi lịch sử ít nhất là có giá trị như mã nguồn. Họ kể cho bạn câu chuyện đầy đủ về lý do tại sao một cái gì đó đã được thực hiện, và làm thế nào nó trở nên như thế này. Người tiếp theo sẽ cần biết.
Tim Williscroft

1
Mã (trong trường hợp này, tên phương thức) sẽ tự ghi lại những gì nó làm. Nhận xét nên giải thích tại sao mã tồn tại hoặc được cấu trúc theo một cách nhất định.
Aaron Kurtzhals

48

Không có gì là lâu dài hơn một sửa chữa tạm thời hoạt động.

Liệu đề nghị của anh ấy có tốt trong thời gian 10 năm không? Nó được sử dụng phổ biến để bình luận từng thay đổi với lỗi mà nó đã sửa. Gần đây hơn (như 3 thập kỷ qua), nhận xét kiểu này được chấp nhận rộng rãi là giảm khả năng duy trì mã - và đó chỉ là với các nhận xét, không phải tên phương thức.

Những gì anh ấy đang đề xuất là bằng chứng thuyết phục hệ thống QC và QA của bạn bị thiếu hụt đáng kể. Theo dõi lỗi và sửa lỗi thuộc hệ thống theo dõi lỗi, không phải mã nguồn. Theo dõi các thay đổi mã nguồn thuộc về hệ thống kiểm soát nguồn. Tham chiếu chéo giữa các hệ thống này cho phép truy tìm các khiếm khuyết đối với mã nguồn .....

Mã nguồn có sẵn cho ngày hôm nay, không phải ngày hôm qua và không phải ngày mai (như trong, bạn không nhập vào nguồn để dự định làm gì trong năm tới) ...


40
+1Nothing is more permanent than a temporary fix that works.
Phản ứng

2
"được chấp nhận rộng rãi" [cần dẫn nguồn]

3
@Graham: Điều này có đủ tốt không, hay nó cần phải được xem xét ngang hàng, được xuất bản trên một tờ báo uy tín .... stackoverflow.com/questions/123936/
Lỗi

14

Vì vậy, nó là một giải pháp tạm thời? Sau đó, sử dụng tên được đề xuất bởi người đánh giá, nhưng đánh dấu phương thức là lỗi thời, để sử dụng nó sẽ tạo ra một cảnh báo mỗi khi ai đó biên dịch mã.

Nếu không, bạn luôn có thể nói rằng 216147 không có ý nghĩa gì trong mã, vì mã không được liên kết với hệ thống theo dõi lỗi (đúng hơn là hệ thống theo dõi lỗi được liên kết với kiểm soát nguồn). Mã nguồn không phải là nơi tốt để tham khảo các vé và phiên bản lỗi, và nếu bạn thực sự cần đặt các tài liệu tham khảo đó, hãy thực hiện nó trong các bình luận.

Lưu ý rằng ngay cả trong các bình luận, chỉ riêng số lỗi không có giá trị. Hãy tưởng tượng bình luận sau đây:

public IEnumerable<Report> FindReportsByDateOnly(DateTime date)
{
    // The following method replaces FindReportByDate, because of the bug 8247 in the
    // reporting system.
    var dateOnly = new DateTime(date.Year, date.Month, date.Day);
    return this.FindReportByDate(dateOnly);
}

private IEnumerable<Report> FindReportsByDate(DateTime date)
{
    Contract.Requires(date.Hour == 0);
    Contract.Requires(date.Minute == 0);
    Contract.Requires(date.Second == 0);

    // TODO: Do the actual work.
}

Hãy tưởng tượng rằng mã được viết cách đây mười năm, rằng bạn vừa tham gia dự án và khi bạn hỏi bạn có thể tìm thấy bất kỳ thông tin nào về lỗi 8247, các đồng nghiệp của bạn nói rằng có một danh sách các lỗi trên trang web của phần mềm hệ thống báo cáo, nhưng trang web đã được làm lại năm năm trước và danh sách các lỗi mới có số lượng khác nhau.

Kết luận: bạn không biết lỗi này là gì.

Mã tương tự có thể đã được viết theo một cách hơi khác:

public IEnumerable<Report> FindReportsByDateOnly(DateTime date)
{
    // The reporting system we actually use is buggy when it comes to searching for a report
    // when the DateTime contains not only a date, but also a time.
    // For example, if looking for reports from `new DateTime(2011, 6, 9)` (June 9th, 2011)
    // gives three reports, searching for reports from `new DateTime(2011, 6, 9, 8, 32, 0)`
    // (June 9th, 2011, 8:32 AM) would always return an empty set (instead of isolating the
    // date part, or at least be kind and throw an exception).
    // See also: http://example.com/support/reporting-software/bug/8247
    var dateOnly = new DateTime(date.Year, date.Month, date.Day);
    return this.FindReportsByDate(dateOnly);
}

private IEnumerable<Report> FindReportsByDate(DateTime date)
{
    Contract.Requires(date.Hour == 0);
    Contract.Requires(date.Minute == 0);
    Contract.Requires(date.Second == 0);

    // TODO: Do the actual work.
}

Bây giờ bạn có một cái nhìn rõ ràng về vấn đề. Ngay cả khi có vẻ như liên kết siêu văn bản ở cuối bình luận đã chết năm năm trước, điều đó không thành vấn đề, vì bạn vẫn có thể hiểu tại sao FindReportsByDateđược thay thế bởi FindReportsByDateOnly.


Ok, chúng tôi đang nhận được ở đâu đó: Tại sao bạn nghĩ rằng mã nguồn không phải là nơi tốt cho số lỗi?
Bojan

1
Bởi vì hệ thống theo dõi lỗi và kiểm soát phiên bản là một nơi tốt hơn cho điều đó. Nó không hoàn toàn giống nhau nhưng tương tự như: stackoverflow.com/q/123936/240613
Arseni Mourzenko

Ok, nói chung có ý nghĩa. Nhưng nếu bạn đang xử lý một cách giải quyết, như sai lệch so với thiết kế chính, tôi đoán sẽ ổn khi để lại một bình luận giải thích những gì đã được thực hiện (và có thể là một số khiếm khuyết trong các bình luận) để ai đó đang đọc mã có thể hiểu được tại sao một cái gì đó đã được thực hiện một cách nhất định.
Bojan

2
Tôi mặc dù chỉ những người tiếp thị mới có thể lập luận logic của việc thêm một cái gì đó mới đã lỗi thời.
mattnz

1
Nếu tại sao mã thực hiện những gì nó làm để khắc phục lỗi thì không rõ ràng khi đọc và bạn cần một lời giải thích dài dòng về lý do tại sao cách giải quyết lại làm gì, bao gồm cả tham chiếu đến nơi có thể tìm thấy tài liệu bên ngoài trong một nhận xét là hợp lý IMO . Có, bạn có thể sử dụng công cụ đổ lỗi kiểm soát nguồn của mình để tìm hiểu thay đổi cách giải quyết được thực hiện như là một phần của và nhận được lời giải thích ở đó nhưng với một cơ sở mã lớn, và đặc biệt là sau khi tái cấu trúc ở nơi khác kết thúc với cách giải quyết có thể trở nên tốn thời gian .
Dan Neely

5

Tôi tìm PerformSqlClient216147Workaroundthêm thông tin rồi PerformRightExpressionCast. Không có nghi ngờ gì cả về tên của chức năng như những gì nó làm, tại sao nó làm điều đó hoặc làm thế nào để có thêm thông tin về nó. Đây là một chức năng rõ ràng sẽ rất dễ tìm kiếm trong mã nguồn.

Với một hệ thống theo dõi lỗi, con số xác định duy nhất sự cố và khi bạn khắc phục lỗi đó trong hệ thống, nó sẽ cung cấp tất cả các chi tiết bạn cần. Đây là một điều rất thông minh để làm trong mã nguồn và sẽ tiết kiệm thời gian cho các nhà phát triển trong tương lai khi cố gắng hiểu tại sao một thay đổi được thực hiện.

Nếu bạn thấy rất nhiều tên hàm này nếu mã nguồn của bạn, thì vấn đề không phải là quy ước đặt tên của bạn. Vấn đề là bạn có phần mềm lỗi.


2
Tôi đồng ý vì có vẻ như PerformanceSqlClient216147Workaround mô tả cả chính xác những gì phương thức làm và đó là lý do tồn tại. Tôi sẽ đánh dấu nó bằng một thuộc tính (C #) dành riêng cho những thứ như vậy cho cửa hàng của bạn và được thực hiện với nó. Numerics có vị trí của chúng trong tên ... tho như trên hy vọng rằng đó không chỉ là phương pháp mà cửa hàng của bạn sử dụng để phân loại những thứ đó. Bão trong một tách trà IMHO. Btw là mã lỗi thực sự ?? Nếu vậy, đồng nghiệp cao cấp của bạn có thể có cơ hội phát hiện ra bài đăng này có thể có hoặc không có vấn đề .... đối với bạn. ;)
nghĩa

3

Có giá trị trong đề xuất đồng nghiệp của bạn; nó cung cấp khả năng truy nguyên bằng cách liên kết các thay đổi với mã với lý do, được ghi lại trong cơ sở dữ liệu lỗi theo số vé đó, tại sao thay đổi được thực hiện.

Tuy nhiên, nó cũng gợi ý rằng lý do duy nhất mà chức năng tồn tại là để khắc phục lỗi. Rằng, nếu vấn đề không phải là vấn đề, bạn sẽ không muốn phần mềm làm điều đó. Có lẽ bạn làm muốn các phần mềm để làm điều này, vì vậy tên của hàm nên giải thích những gì nó làm và tại sao các miền vấn đề đòi hỏi phải được thực hiện; không phải tại sao cơ sở dữ liệu lỗi cần nó. Giải pháp sẽ trông giống như một phần của ứng dụng, không giống như hỗ trợ ban nhạc.


3
điều này nên được giải thích trong các ý kiến ​​của phương pháp, không phải tên của nó.
Arseni Mourzenko

2
Tôi đồng ý với câu trả lời của bạn nói chung, nhưng tôi cũng đồng ý với MainMa: thông tin meta về một phương thức nên có trong các bình luận, không phải trong tên.
Robert Harvey

3

Tôi nghĩ rằng cả bạn và anh ấy đã nhận được toàn bộ điều này ra khỏi tỷ lệ.

Tôi đồng ý với lập luận kỹ thuật của bạn, nhưng vào cuối ngày, nó sẽ không tạo ra sự khác biệt lớn như vậy, đặc biệt nếu đây là một sửa chữa tạm thời có thể được gỡ bỏ khỏi codebase trong vài ngày / tuần / tháng.

Tôi nghĩ bạn nên đặt cái tôi của bạn trở lại vào hộp của nó, và hãy để anh ấy có con đường của riêng mình. (Nếu anh ấy cũng lắng nghe, tôi sẽ nói rằng các bạn cần phải thỏa hiệp. Cả hai đều trở lại trong hộp của họ.)

Dù bằng cách nào, bạn và anh ấy có những điều tốt hơn để làm.


Điểm lấy. Nhưng tôi sẽ không đánh giá thấp sức mạnh của bản ngã :)
Bojan

1

Sẽ bao gồm số lỗi bên trong tên phương thức cho một cách giải quyết tạm thời được coi là thực hành xấu?

Vâng.

Lý tưởng nhất, lớp của bạn nên ánh xạ tốt nhất để / thực hiện một khái niệm trong luồng / trạng thái ứng dụng của bạn. Tên của các API của lớp này sẽ phản ánh những gì chúng làm với trạng thái của lớp, để mã máy khách có thể dễ dàng sử dụng lớp đó (nghĩa là không chỉ định một tên theo nghĩa đen không có nghĩa gì trừ khi bạn đọc cụ thể về nó).

Nếu một phần của API công khai của lớp đó về cơ bản nói "thực hiện thao tác Y được mô tả trong tài liệu / vị trí X" thì khả năng hiểu API của người khác sẽ phụ thuộc vào:

  1. họ biết những gì cần tìm trong tài liệu bên ngoài

  2. họ biết nơi để tìm tài liệu bên ngoài

  3. họ dành thời gian và nỗ lực và thực sự tìm kiếm.

Sau đó, một lần nữa, tên phương thức của bạn thậm chí không đề cập đến vị trí "vị trí X" cho khuyết điểm này.

Nó chỉ giả định (không có lý do thực tế nào) rằng mọi người có quyền truy cập vào mã, cũng có quyền truy cập vào hệ thống theo dõi lỗi và hệ thống theo dõi sẽ vẫn tồn tại chừng nào mã ổn định sẽ tồn tại.

Ít nhất, nếu bạn biết lỗi sẽ luôn có thể truy cập được ở cùng một vị trí và điều này sẽ không thay đổi (như số lỗi của Microsoft ở cùng một URL trong 15 năm qua), bạn nên cung cấp liên kết đến vấn đề trong tài liệu của API.

Thậm chí, có thể có cách giải quyết cho các lỗi khác, ảnh hưởng nhiều hơn API của một lớp. Bạn sẽ làm gì sau đó?

Có các API có cùng số lỗi trong nhiều lớp ( data = controller.get227726FormattedData(); view.set227726FormattedData(data);không thực sự cho bạn biết nhiều và chỉ làm cho mã trở nên tối nghĩa hơn.

Bạn có thể quyết định rằng tất cả các lỗi khác được giải quyết bằng cách sử dụng các tên mô tả của thao tác ( data = controller.getEscapedAndFormattedData(); view.setEscapedAndFormattedData(data);), ngoại trừ trong trường hợp lỗi 216147 của bạn (phá vỡ nguyên tắc thiết kế "ít đầu hàng nhất" - hoặc nếu bạn muốn đặt nó theo cách đó, thì nó sẽ tăng số đo "WTFs / LOC" của mã của bạn).

TL; DR: Thực hành tồi! Về phòng đi!


0

Các mục tiêu chính của một lập trình viên nên là mã làm việc, và, sự rõ ràng của biểu thức.

Đặt tên cho một phương pháp giải pháp (.... Workaround). Dường như sẽ đạt được mục tiêu này. Hy vọng ở giai đoạn nào đó, vấn đề tiềm ẩn sẽ được khắc phục và phương pháp khắc phục đã được loại bỏ.


0

Đối với tôi, việc đặt tên một phương thức sau một lỗi cho thấy rằng lỗi không được giải quyết hoặc nguyên nhân gốc không được xác định. Nói cách khác, nó cho thấy vẫn còn một ẩn số. Nếu bạn đang khắc phục lỗi trong hệ thống của bên thứ 3, thì cách giải quyết của bạn là một giải pháp vì bạn biết nguyên nhân - họ không thể hoặc sẽ không khắc phục được.

Nếu một phần của việc tương tác với SqlClient yêu cầu bạn thực hiện một biểu thức đúng, thì mã của bạn sẽ đọc "PerformanceRightExpressionCast ()". Bạn luôn có thể nhận xét mã để giải thích tại sao.

Tôi đã dành 4 năm rưỡi để bảo trì phần mềm. Một trong những điều làm cho mã khó hiểu khi nhảy vào là mã được viết theo cách nó chỉ là do lịch sử. Nói cách khác, đó không phải là cách nó sẽ hoạt động nếu nó được viết ngày hôm nay. Tôi không nói đến chất lượng, mà là về quan điểm.

Một đồng nghiệp của tôi đã từng nói "Khi sửa một lỗi, hãy tạo mã theo cách mà nó phải có." Cách tôi diễn giải đó là "Thay đổi mã thành giao diện nếu lỗi này không bao giờ tồn tại."

Hậu quả:

  1. Thông thường, kết quả là ít mã hơn.
  2. Mã đơn giản
  3. Ít tham chiếu hơn đến các lỗi trong mã nguồn
  4. Ít rủi ro về hồi quy trong tương lai (một khi thay đổi mã được xác minh đầy đủ)
  5. Dễ dàng phân tích hơn vì các nhà phát triển không phải tự tạo gánh nặng cho việc học lịch sử không còn phù hợp.

Mã nguồn không cần cho tôi biết làm thế nào nó đến trạng thái hiện tại. Kiểm soát phiên bản có thể cho tôi biết lịch sử. Tôi cần mã nguồn đơn giản là ở trạng thái cần thiết để làm việc. Điều đó nói rằng, một bình luận "// bug 12345" không thường xuyên không phải là một ý tưởng tồi, nhưng nó bị lạm dụng.

Vì vậy, khi quyết định có đặt tên phương thức của bạn là 'PerformanceSqlClient216147Workaround' hay không, hãy tự hỏi mình những câu hỏi sau:

  1. Nếu tôi đã biết về lỗi 216147 trước khi viết mã, tôi sẽ xử lý nó như thế nào?
  2. Cách giải quyết là gì? Nếu ai đó chưa bao giờ nhìn thấy mã này trước đây để xem nó, liệu họ có thể làm theo nó không? Việc kiểm tra hệ thống theo dõi lỗi có cần thiết để biết mã này hoạt động như thế nào không?
  3. Mã này tạm thời như thế nào? Theo kinh nghiệm của tôi, các giải pháp tạm thời thường trở thành vĩnh viễn, như @mattnz chỉ ra.
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.