Tôi nên làm gì với tư cách là người đánh giá khi code mã bị lỗi xấu?


18

Tôi làm việc tại một dự án được thiết kế tồi, áp đảo, nơi các đánh giá mã bắt buộc đã được giới thiệu vài tháng trước.

Tôi đã được yêu cầu xem lại một đoạn mã đáng kể thực hiện một tính năng mới. Nó mang những sai sót giống như phần còn lại của cơ sở mã của chúng tôi. Tôi hiểu rằng ở một mức độ lớn, những lỗ hổng đó len lỏi vào mã mới, vd. bằng cách phải kế thừa từ lớp được thiết kế kém hoặc thực hiện giao diện được thiết kế kém trong khi vẫn giữ được tính tương thích và tôi thực sự không thể cung cấp giải pháp tốt hơn nhiều mà không liên quan đến việc viết lại một nửa cơ sở mã. Nhưng tôi cảm thấy rằng từ quan điểm kỹ thuật, sẽ không tốt cho một cơ sở mã đã bị hỏng mà chúng tôi còn phá vỡ nó nhiều hơn nữa. Mã tôi đang xem xét chắc chắn là xấu, nhưng nó phải là nếu tính năng này được triển khai.

Làm thế nào tôi nên cư xử liên quan đến đánh giá cụ thể này? Có cách nào để tôi duy trì tính toàn vẹn và duy trì tính xây dựng không?

Xin lưu ý rằng tôi đang hỏi về ranh giới của đánh giá mã trong bối cảnh này. Tôi nhận ra rằng vấn đề là do các yếu tố khác bao gồm văn hóa tổ chức và công việc, nhưng điều tôi muốn biết là làm thế nào để tự xử lý việc xem xét.


1
Có phải nhà phát triển tài liệu tại sao nó được thực hiện như thế này và thậm chí có thể viết một vấn đề cho vấn đề cốt lõi trên trình theo dõi vấn đề?
Luc Franken

Đáng sợ, và không.
Đỏ

4
Có bất kỳ sự thèm ăn trong tổ chức của bạn để làm một cái gì đó về các khoản nợ kỹ thuật?
Robert Harvey

5
Nếu mã không sai khi xem xét môi trường, tôi sẽ không tấn công mã. Hầu hết kể từ khi bạn viết, bạn không thấy sự cải thiện thực sự có thể tại thời điểm này. Nó sẽ tạo ra xung đột mà không có cơ hội để cải thiện. Những gì tôi sẽ làm là dạy để tài liệu tốt hơn như là một bước đầu tiên. Thứ hai tạo ra một thủ tục để họ viết các vấn đề rõ ràng. Điều đó sẽ dẫn đến 2 điều: tài liệu về vấn đề này để tiếp theo có thể hoạt động nhanh hơn. Và ngoài ra, bạn có được một danh sách các vấn đề cụ thể có khả năng được khắc phục. Tôi thích GitHub đề cập bởi vì bạn thấy nó lặp lại bao nhiêu lần nếu họ gắn thẻ nó.
Luc Franken

Câu trả lời:


25

Đơn giản:

1. Tài liệu nợ kỹ thuật của bạn

Bạn đã xác định được một đoạn mã hoạt động nhưng có một số vấn đề kỹ thuật với nó. Đây là nợ kỹ thuật . Giống như các loại nợ khác, nó trở nên tồi tệ hơn theo thời gian nếu không được xử lý.

Bước đầu tiên trong việc xử lý nợ kỹ thuật là ghi chép lại. Thực hiện việc này bằng cách thêm các mục trong trình theo dõi vấn đề của bạn mô tả khoản nợ. Điều này sẽ giúp bạn có được một bức tranh rõ ràng hơn về mức độ nghiêm trọng của vấn đề và cũng sẽ giúp đưa ra một kế hoạch để giải quyết nó.

2. Dần dần trả nợ

Sửa đổi quy trình phát triển phần mềm của bạn để trả lại nợ kỹ thuật. Điều này có thể liên quan đến việc chạy nước rút đôi khi, hoặc đơn giản là giải quyết các khoản nợ theo định kỳ (ví dụ: 2 mục mỗi tuần). Phần quan trọng để đảm bảo rằng bạn đang xử lý khoản nợ của mình nhanh hơn khoản nợ của mình (nợ, thậm chí là nợ kỹ thuật, có lãi đối với khoản nợ đó).

Khi bạn đã đạt đến điểm mà bạn không còn Thiếu hụt kỹ thuật, bạn đang trên đường đến một cơ sở mã hóa lành mạnh hơn :)


5

Như một lưu ý phụ: tìm kiếm một công việc mới. Điều này sẽ không tốt hơn.

Mục tiêu của mã bạn đang xem xét là:

  • Để gửi một tính năng, mà nên làm việc theo yêu cầu.

  • Để giảm sự tăng trưởng của nợ kỹ thuật.

Mục tiêu đầu tiên được xem xét bằng cách kiểm tra xem các đơn vị, tích hợp, hệ thống và kiểm tra chức năng có ở đây không, có liên quan hay không và chúng bao gồm tất cả các tình huống phải kiểm tra. Bạn cũng phải kiểm tra niềm tin mà tác giả ban đầu có thể có về ngôn ngữ lập trình, điều này có thể dẫn đến các lỗi tinh vi hoặc mã giả vờ làm điều gì đó khác với những gì nó thực sự làm.

Mục tiêu thứ hai là câu hỏi của bạn tập trung vào. Một mặt, mã mới dự kiến ​​sẽ không làm tăng nợ kỹ thuật. Mặt khác, phạm vi của đánh giá là chính mã, nhưng trong bối cảnh của toàn bộ cơ sở mã. Từ đó, bạn, với tư cách là người đánh giá, có thể mong đợi hai cách tiếp cận từ tác giả ban đầu:

  • Mã bên ngoài không phải là lỗi của tôi. Tôi chỉ thực hiện tính năng này và không quan tâm đến toàn bộ cơ sở mã.

    Theo quan điểm này, mã sẽ sao chép các lỗ hổng của codebase, và do đó chắc chắn sẽ làm tăng nợ kỹ thuật: mã xấu hơn luôn luôn tệ hơn.

    Mặc dù đây là một cách tiếp cận ngắn hạn hợp lệ, nhưng về lâu dài, nó sẽ dẫn đến sự chậm trễ và năng suất thấp, và cuối cùng dẫn đến quá trình phát triển trở nên đắt đỏ và rủi ro, sản phẩm sẽ ngừng phát triển.

  • Viết mã mới là một cơ hội để tái cấu trúc một di sản.

    Trong viễn cảnh này, ảnh hưởng của các lỗ hổng của mã kế thừa đối với mã mới có thể bị hạn chế. Hơn nữa, các khoản nợ kỹ thuật có thể được giảm, hoặc ít nhất là không tăng tỷ lệ thuận với sự tăng trưởng của mã.

    Mặc dù đây là một cách tiếp cận dài hạn hợp lệ, nhưng nó có những rủi ro ngắn hạn. Vấn đề chính là, trong ngắn hạn, đôi khi sẽ mất nhiều thời gian hơn để vận chuyển tính năng cụ thể. Một khía cạnh quan trọng khác là nếu mã kế thừa chưa được kiểm tra, việc tái cấu trúc nó có nguy cơ rất lớn trong việc đưa ra hồi quy.

Tùy thuộc vào quan điểm bạn muốn khuyến khích, bạn có thể có xu hướng khuyên người đánh giá tái cấu trúc nhiều hơn hay không. Trong mọi trường hợp, đừng mong đợi đoạn mã hoàn hảo, sạch sẽ với kiến ​​trúc và thiết kế đẹp bên trong một cơ sở mã tào lao. Điều bạn không nên khuyến khích là hành vi mà một nhà phát triển có kiến ​​thức phải làm việc với một cơ sở mã hóa xảo quyệt cố gắng làm tốt phần của mình . Thay vì làm cho mọi thứ đơn giản hơn, nó chỉ làm cho chúng phức tạp hơn trước đó. Bây giờ, thay vì mã xấu thống nhất, bạn có một phần với các mẫu thiết kế, một phần khác với mã rõ ràng, rõ ràng, một phần khác được tái cấu trúc rộng rãi theo thời gian và không có sự thống nhất nào.

Ví dụ, hãy tưởng tượng rằng bạn đang khám phá một cơ sở mã di sản của một trang web cỡ trung bình. Bạn ngạc nhiên vì thiếu cấu trúc thông thường và thực tế là việc ghi nhật ký, khi hoàn thành, được thực hiện bằng cách nối thêm nội dung vào tệp văn bản bằng tay, thay vì sử dụng khung ghi nhật ký. Bạn quyết định cho tính năng mới để sử dụng MVC và khung đăng nhập.

Đồng nghiệp của bạn đang triển khai một tính năng khác và rất ngạc nhiên khi thiếu ORM nơi người ta sẽ tạo ra kích thước hoàn hảo. Vì vậy, anh ta bắt đầu sử dụng một ORM.

Cả bạn và đồng nghiệp của bạn đều không thể trải qua hàng trăm ngàn dòng mã để sử dụng MVC, hoặc khung ghi nhật ký hoặc ORM ở mọi nơi. Trên thực tế, nó sẽ đòi hỏi nhiều tháng làm việc: tưởng tượng giới thiệu MVC; nó sẽ kéo dài bao lâu? Hoặc điều gì về một ORM trong các tình huống trong đó các truy vấn SQL được tạo ra một cách hỗn loạn thông qua ghép nối (với các vị trí không thường xuyên cho SQL Injection) bên trong mã không ai có thể hiểu được?

Bạn nghĩ rằng bạn đã làm một công việc tuyệt vời, nhưng bây giờ, một nhà phát triển mới tham gia dự án phải đối mặt với sự phức tạp hơn nhiều so với trước đây:

  • Cách xử lý các yêu cầu cũ,

  • Cách thức MVC

  • Cơ chế ghi nhật ký cũ,

  • Khung đăng nhập,

  • Truy cập trực tiếp vào cơ sở dữ liệu với các truy vấn SQL được xây dựng nhanh chóng,

  • ORM.

Trong một dự án tôi đang làm việc, có bốn khung ghi nhật ký (!) Được sử dụng cạnh nhau (cộng với ghi nhật ký thủ công). Lý do là vì mỗi khi ai đó muốn đăng nhập công cụ, không có cách tiếp cận chung để làm điều đó, vì vậy thay vì học một khung mới (trong tất cả các trường hợp chỉ được sử dụng trong 5% của cơ sở mã), người ta chỉ cần thêm một cách khác đã biết. Hãy tưởng tượng sự lộn xộn.

Một cách tiếp cận tốt hơn sẽ là cấu trúc lại cơ sở mã một bước. Lấy một lần nữa ví dụ về ghi nhật ký, tái cấu trúc sẽ bao gồm các bước nhỏ sau:

  • Tìm tất cả các địa điểm nơi ghi nhật ký cũ được thực hiện (nghĩa là khi tệp nhật ký được truy cập trực tiếp) và đảm bảo tất cả chúng đều gọi các phương thức giống nhau.

  • Di chuyển mã này đến một thư viện chuyên dụng, nếu có. Tôi không muốn đăng nhập logic lưu trữ trong lớp giỏ hàng của tôi.

  • Sửa đổi, nếu cần, giao diện của các phương thức đăng nhập. Chẳng hạn, chúng ta có thể thêm một mức cho biết tin nhắn là không chính thức, hay là một cảnh báo hay lỗi.

  • Sử dụng các phương thức mới được cấu trúc lại trong tính năng mới.

  • Di chuyển sang khung ghi nhật ký: mã bị ảnh hưởng duy nhất là mã trong thư viện chuyên dụng.


1
Câu trả lời tuyệt vời cho đến đoạn cuối cùng. Cho dù bạn có ý định hay không, bạn đang ngụ ý rằng các thực tiễn tốt không nên được sử dụng cho mã mới. -1
RubberDuck

2
@RubberDuck: không phải là về cách thực hành tốt, mà là về cách viết mã hoàn toàn khác với cơ sở mã còn lại. Tôi đã là nhà phát triển đó và tôi đã thấy hậu quả của những gì tôi đã làm: có mã tốt hơn đáng kể trong số các mã xấu làm cho mọi thứ trở nên tồi tệ hơn; Điều làm cho nó tốt hơn là cải thiện cơ sở mã thông qua các bước tái cấu trúc nhỏ. Tôi sẽ thêm một ví dụ trong câu trả lời của tôi trong vài phút.
Arseni Mourzenko

Tôi sẽ DV một lần nữa nếu tôi có thể. Việc chỉnh sửa làm cho nó tồi tệ hơn. Có bốn phương pháp khác nhau để làm một cái gì đó theo một cách mới là xấu, nhưng đó là lỗi của anh chàng thêm khung đăng nhập thứ hai. Bản thân nó không phải là xấu khi vẽ một đường thẳng trên cát và có mã sạch bên cạnh mã thối.
RubberDuck

@RubberDuck: Không phải là thêm khung đăng nhập thứ hai , mà là khung đầu tiên. Anh chàng thêm khung đăng nhập thứ hai thực hiện điều đó chỉ vì cái thứ nhất chỉ được sử dụng trên một tính năng nhỏ; nếu codebase được tái cấu trúc như tôi khuyên, điều này sẽ không xảy ra.
Arseni Mourzenko

Tôi nghĩ rằng bạn và tôi đồng ý, nhưng câu trả lời của bạn đọc theo cách không khuyến khích cải thiện. Tôi không thể lên tàu với điều đó.
RubberDuck

3

Nếu bạn đang thực hiện đánh giá mã như một phần của quá trình phát triển của bạn; sau đó, bạn phải đặt quy tắc mà bạn 'phán xét' mã bạn đang xem xét.

Điều này sẽ đi vào 'định nghĩa hoàn thành' của bạn và có thể là hướng dẫn về kiểu dáng, tài liệu kiến ​​trúc cho cơ sở mã hoặc phân tích tĩnh, kiểm tra các yêu cầu pháp lý, bất cứ điều gì công ty quyết định là yêu cầu của nó về 'chất lượng mã'

Một khi bạn có điều này trong các đánh giá mã địa điểm trở thành một vấn đề tất nhiên, có hướng dẫn về phong cách được tuân theo, chúng tôi có tỷ lệ bao phủ yêu cầu kiểm tra, v.v.

Nếu bạn không có điều này thì các đánh giá mã có thể trở thành một cuộc chiến của những người có mã hóa lớn nhất hoặc, như trong tình huống của bạn, việc đặt câu hỏi về phán đoán sẽ gọi về tái cấu trúc so với các tính năng được thực hiện trước thời hạn. Đó chỉ là một sự lãng phí thời gian của mọi người.


3

Vấn đề chính của bạn là việc xem xét mã trên một tính năng mới quan trọng là không đúng lúc để có cuộc thảo luận này. Tại thời điểm đó, đã quá muộn để thực hiện bất cứ điều gì ngoại trừ những thay đổi nhỏ. Nơi thích hợp là trong giai đoạn lập kế hoạch, hoặc trong một đánh giá thiết kế sơ bộ muộn nhất. Nếu công ty của bạn không thực hiện những đánh giá sớm đó ít nhất là không chính thức, trước tiên bạn nên thay đổi văn hóa đó.

Bước tiếp theo là để bản thân được mời tham gia các cuộc họp đó và có những ý tưởng hữu ích tại các cuộc họp đó. Chủ yếu là điều đó có nghĩa là không cố gắng thay đổi mọi thứ qua đêm, nhưng tìm kiếm những mảnh nhỏ có kích thước cắn bạn có thể cô lập và giải quyết. Những khối đó sẽ tăng lên đáng kể theo thời gian.

Nói cách khác, mấu chốt là thường xuyên đề xuất các thay đổi nhỏ hơn khi bắt đầu dự án, thay vì bị bắn hạ gợi ý những thay đổi lớn hơn về cuối.


2

Ở những nơi tôi đã thực hiện đánh giá mã, tôi sẽ chấp nhận và chấp nhận việc gửi mã, nếu nó đi kèm với một cam kết thực hiện (ít nhất là) một số tái cấu trúc. Là một lỗi được đệ trình, như một câu chuyện, hoặc một lời hứa sẽ gửi một đánh giá khác với (một số) tái cấu trúc được thực hiện.

Trong những trường hợp này, nếu tôi là người viết mã để xem xét, tôi thường chuẩn bị hai thay đổi, một thay đổi với (các) tính năng mới của tôi hoặc sửa lỗi, sau đó một thay đổi có VÀ một số dọn dẹp. Bằng cách đó, các thay đổi dọn dẹp không làm mất đi (các) tính năng mới hoặc sửa lỗi, nhưng dễ dàng được chỉ ra là một mã thông báo "vâng, tôi biết điều này không khắc phục được các vấn đề này, nhưng ở đó là" làm sạch tinh khiết "mà không".

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.