Ngăn chặn mã không dùng nữa để biên dịch sau khi đến hạn chót [đã đóng]


68

Trong nhóm của tôi, chúng tôi đã dọn dẹp rất nhiều thứ cũ trong một dự án nguyên khối lớn (toàn bộ lớp học, phương pháp, v.v.).

Trong quá trình làm sạch đó, tôi đã tự hỏi liệu có một loại chú thích hay thư viện nào lạ hơn bình thường không @Deprecated. Điều này @FancyDeprecatedsẽ ngăn việc xây dựng dự án thành công nếu bạn chưa xóa mã cũ không sử dụng sau khi một ngày cụ thể trôi qua.

Tôi đã tìm kiếm trên Internet và không tìm thấy bất cứ thứ gì có khả năng được mô tả dưới đây:

  • phải là một chú thích, hoặc một cái gì đó tương tự, để đặt vào mã bạn định xóa trước một ngày cụ thể
  • trước ngày đó mã sẽ biên dịch và mọi thứ sẽ hoạt động bình thường
  • sau ngày đó mã sẽ không được biên dịch và nó sẽ cho bạn một thông báo cảnh báo bạn về vấn đề này

Tôi nghĩ rằng tôi đang tìm kiếm một con kỳ lân ... Có công nghệ tương tự cho bất kỳ ngôn ngữ chương trình nào không?

Như một kế hoạch BI đang nghĩ đến khả năng tạo ra phép thuật với một số bài kiểm tra đơn vị về mã dự định sẽ bị xóa mà bắt đầu thất bại ở "thời hạn". Bạn nghĩ gì về điều này? Còn ý tưởng nào hay hơn không?


168
Khấu hao được thực hiện cho một phiên bản , không phải là một ngày . Nếu bạn muốn mọi người ngừng sử dụng các tính năng không dùng nữa, hãy phát hành phiên bản không có chúng. Điều đó sẽ thu hút sự chú ý của họ và họ luôn có thể quay lại nếu họ chưa làm được. Rất nhiều người bị mắc kẹt trên các phiên bản cũ. Phá vỡ chương trình của họ không phải là cách để đi.
isanae

4
Kế hoạch B nghe có vẻ vững chắc. Với những lợi thế bổ sung mà bạn có thể đưa ra nhận xét trong bài kiểm tra đơn vị về lý do tại sao nó không được chấp nhận. Thêm nhận xét vào mã nguồn sẽ không giúp dễ đọc trong một khối nguyên khối lớn
dwana

53
Nghe có vẻ như một con kỳ lân thực sự xấu xa. Bạn có một chút phần mềm biên dịch tốt, vượt qua tất cả các bài kiểm tra và bạn đã chuyển nó cho khách hàng. Sau đó một ngày, bạn kiểm tra lại phần mềm và nó sẽ không được xây dựng, ngay cả trên cùng một nền tảng phát triển. Bây giờ bạn buộc phải sửa đổi mã mà trước đó đã vượt qua thử nghiệm chính thức hoặc thực hiện các hành vi xấu xa như quay ngược đồng hồ của máy tính.
Simon B

6
Làm cho nó @ Deprecated_RemoveMe_2018_06_01 và sau đó vào 2018-06-01 xóa chính chú thích. Voila, tất cả mã của bạn bằng cách sử dụng chú thích sẽ không còn được biên dịch! (vì chú thích không được tìm thấy)
user253751

65
Nhiều năm trong tương lai, một nhà phát triển mới được tuyển dụng sẽ hỏi: tại sao thời gian trên máy chủ xây dựng được đặt thành tháng 1 năm 2016? Và anh chàng ở đó trong 10 năm sẽ nói với anh ta rằng điều đó là cần thiết hoặc việc xây dựng bị phá vỡ ở những nơi ngẫu nhiên. Thở dài.
Wilbert

Câu trả lời:


62

Tôi không nghĩ rằng đây sẽ là một tính năng hữu ích khi nó thực sự cấm biên dịch. Khi vào ngày 01/06/2018, phần lớn mã sẽ không được biên dịch vào ngày hôm trước, nhóm của bạn sẽ nhanh chóng xóa chú thích đó một lần nữa, mã có được dọn sạch hay không.

Tuy nhiên, bạn có thể thêm một số chú thích tùy chỉnh vào mã như

@Deprecated_after_2018_07_31

và xây dựng một công cụ nhỏ để quét các chú thích đó. (Một lớp lót đơn giản trong grep sẽ làm điều đó, nếu bạn không muốn sử dụng sự phản chiếu). Trong các ngôn ngữ khác ngoài Java, có thể sử dụng một nhận xét được tiêu chuẩn hóa phù hợp cho "grepping" hoặc định nghĩa tiền xử lý.

Sau đó chạy công cụ đó ngay trước hoặc sau ngày cụ thể và nếu nó vẫn tìm thấy chú thích đó, hãy nhắc nhở nhóm dọn dẹp các phần mã đó một cách khẩn cấp.


9
@Bergi: này, đây chỉ là một ví dụ, OP có thể sử dụng các phiên bản hoặc thẻ ngày, bất cứ điều gì họ thích trong việc kiểm soát của họ.
Doc Brown

4
Tôi không thấy bất kỳ lợi thế nào khi thực hiện điều này chỉ bằng cách sử dụng các tính năng khấu hao thông thường và xem sản lượng của trình biên dịch vào ngày cụ thể. Có vẻ như việc sử dụng thời gian của nhà phát triển kém để thực hiện lại một cái gì đó đã tồn tại khá nhiều. Ngay cả khi bạn đã có rất nhiều cảnh báo (đáng để bạn dành thời gian dọn dẹp), chắc chắn bạn có thể yêu cầu trình biên dịch nhổ tất cả các cảnh báo ra một tệp văn bản và sau đó grep hoặc tìm kiếm nó.
jpmc26

4
@jpaugh Tôi khuyên bạn không nên chìm hàng giờ (lưu ý, thời gian = tiền) vào việc xây dựng các công cụ mới để thực hiện các nhiệm vụ mà bạn có thể thực hiện hiệu quả với các công cụ hiện có, bất kể những công cụ đó có thể là gì.
jpmc26

3
@ jpmc26: Tôi thấy hai ưu điểm (nhỏ): không nhận được hàng tấn cảnh báo khấu hao (sẽ có nguy cơ xem xét các yếu tố quan trọng hơn) và khả năng đưa ra các tiêu chí khấu hao khác nhau (ngày, phiên bản, bất cứ điều gì) cho các phần mã khác nhau. Hơn nữa, OP đã hỏi rõ ràng về việc khấu hao khớp nối với một ngày.
Doc Brown

7
Tôi sẽ +1 nếu bạn chỉ sử dụng thứ tự YYYY-MM-DD cho ngày trong ví dụ của bạn, bởi vì tôi chỉ từng thấy thứ tự mơ hồ ?? - ?? - YYYY gây đau đớn và hiểu lầm.
mtraceur

284

Điều này sẽ tạo thành một tính năng được gọi là một quả bom hẹn giờ . KHÔNG TẠO BOMBS THỜI GIAN.

Mã, cho dù bạn cấu trúc và ghi chép nó tốt đến đâu, sẽ biến thành một hộp đen gần như không hiểu được nếu nó sống quá một độ tuổi nhất định. Điều cuối cùng mà bất cứ ai trong tương lai cần là một chế độ thất bại kỳ lạ khác khiến họ hoàn toàn bất ngờ, vào thời điểm tồi tệ nhất có thể, và không có một biện pháp khắc phục rõ ràng. Hoàn toàn không có lý do cho việc cố ý tạo ra một vấn đề như vậy.

Nhìn vào nó theo cách này: nếu bạn có tổ chức và nhận thức được cơ sở mã của mình đủ để bạn quan tâm đến sự lỗi thời và theo dõi nó, thì bạn không cần một cơ chế trong mã để nhắc nhở bạn. Nếu bạn không, rất có thể là bạn cũng không cập nhật về các khía cạnh khác của cơ sở mã và có thể sẽ không thể trả lời báo động kịp thời và chính xác. Nói cách khác, bom hẹn giờ không phục vụ mục đích tốt cho bất cứ ai. Chỉ cần nói không!


74
+1 Điều này sẽ cắn bạn. Vài tháng sau. Vào thứ Sáu, giống như bạn đang cố gắng triển khai khẩn cấp. Và đó là một ngày cuối tuần dài, vì vậy tất cả những người biết bất cứ điều gì về nó đều ra khỏi văn phòng. Đừng làm điều đó.
Roger Lipscombe

3
Đồng ý. Lỗi thời là một vấn đề tổ chức, không phải là một vấn đề mã hóa. Tôi vẫn có thể cắm vào Apple] [và viết BASIC, không có gì ngăn cản tôi. Nhưng, tôi có muốn không?

19
Giải pháp chính xác, đi theo hướng "có tổ chức và nhận thức" của bạn, là đưa ra một lỗi trong hệ thống theo dõi lỗi của bạn, nói "Xóa <như vậy và như vậy>", với khung thời gian được đề xuất trong các nhận xét. Và sau 6 tháng, khi đánh giá lỗi xuất hiện để tìm ra lỗi nào sẽ được sửa trong bản phát hành tiếp theo, nếu khung thời gian đó sắp xảy ra, bạn nói "đã đến lúc phải làm điều này". Đó là quản lý dự án cơ bản.
Các cuộc đua nhẹ nhàng trong quỹ đạo

1
Trong thực tế, nếu lịch phát hành của bạn đủ dự đoán, chỉ cần đánh dấu nó ngay bây giờ.
Các cuộc đua nhẹ nhàng trong quỹ đạo

13
Tham khảo bình luận của isanae để biết cách thay thế: " Nếu bạn muốn mọi người ngừng sử dụng các tính năng không dùng nữa, hãy phát hành phiên bản không có chúng. Điều đó sẽ khiến họ chú ý và họ luôn có thể quay lại nếu chưa thể làm được. "
Stevoisiak

70

Trong C #, bạn sẽ sử dụng ObsoleteAttributetheo cách sau:

  • Trong phiên bản 1, bạn gửi tính năng này. Một phương thức, lớp học, bất cứ điều gì.
  • Trong phiên bản 2, bạn gửi một tính năng tốt hơn nhằm thay thế tính năng ban đầu. Bạn đặt thuộc tính Lỗi thời trên tính năng, đặt thành "cảnh báo" và gửi cho nó một thông báo "Tính năng này không được chấp nhận. Thay vào đó, hãy sử dụng tính năng tốt hơn. Trong phiên bản 3 của thư viện này, sẽ được phát hành như vậy một ngày, việc sử dụng tính năng này sẽ là một lỗi. " Bây giờ người dùng của tính năng vẫn có thể sử dụng nó, nhưng có thời gian để cập nhật mã của họ để sử dụng tính năng mới.
  • Trong phiên bản 3, bạn cập nhật thuộc tính là lỗi thay vì cảnh báo và cập nhật thông báo để nói "Tính năng này không được chấp nhận. Thay vào đó, hãy sử dụng tính năng tốt hơn. Trong phiên bản 4 của thư viện này, sẽ được phát hành như vậy một ngày, tính năng này sẽ ném. " Người dùng không chú ý đến cảnh báo trước đó của bạn vẫn nhận được một thông báo hữu ích cho họ biết cách khắc phục sự cố và họ phải khắc phục vì giờ mã của họ không được biên dịch.
  • Trong phiên bản 4, bạn thay đổi tính năng để nó ném một số ngoại lệ nghiêm trọng và thay đổi thông báo để nói rằng tính năng này sẽ bị xóa hoàn toàn trong phiên bản tiếp theo.
  • Trong phiên bản 5, bạn loại bỏ hoàn toàn tính năng này và nếu người dùng phàn nàn, thì, bạn đã cho họ ba chu kỳ phát hành cảnh báo công bằng và họ luôn có thể tiếp tục sử dụng phiên bản 2 nếu họ cảm thấy mạnh mẽ về nó.

Ý tưởng ở đây là tạo ra một thay đổi đột phá không gây đau đớn nhất có thể cho người dùng bị ảnh hưởng và để đảm bảo rằng họ có thể tiếp tục sử dụng tính năng này cho ít nhất một phiên bản của thư viện.


2
Tôi tin rằng đây là cách tiếp cận đúng nhưng tôi sẽ thay đổi một điều ... đó là hoán đổi "nếu người dùng phàn nàn" thành "khi người dùng phàn nàn"
Liath

10
Loại bỏ cơ thể cùng lúc với việc thay đổi thành một lỗi có vẻ kỳ lạ. Một trong những lợi thế của phiên bản lỗi không dùng nữa là nó cho phép mã được xây dựng so với các phiên bản trước tiếp tục hoạt động trong khi ngăn không cho mã mới được biên dịch sử dụng. Do đó, bạn vẫn tương thích ABI, trong khi cố tình phá vỡ tính tương thích API. Tất nhiên thế giới hoàn hảo bạn sẽ có phiên bản kiểu semver, v.v., như vậy bạn sẽ không bao giờ chạy mã mới với một ứng dụng được biên dịch trước đó, nhưng nhiều dự án không bao giờ đạt được lý tưởng đó.
Kevin Cathcart

@KevinCathcart: Đó là một điểm tốt; có thể một giai đoạn khác trong đó được bảo hành! Tôi sẽ cập nhật văn bản.
Eric Lippert

1
Trên thực tế, nếu bạn đang thực hiện SemVer, bạn có thể chuyển thẳng từ phiên bản XY0 (bất kỳ sự phản đối nào phải là một bản phát hành nhỏ) để loại bỏ hoàn toàn trong X + 1.0.0. Tôi muốn nói rằng thật tuyệt khi giữ thêm một chút, (với X + 2.0.0?), Nhưng quá trình năm bước này có lẽ là mạ vàng hoa huệ. Bước tiếp theo sau "cảnh báo" phải là "lỗi nghiêm trọng" (vì tính năng không dùng nữa được thay thế bằng mã tạo lỗi). Vì libfoo.so.2libfoo.so.3có thể cùng tồn tại với nhau tốt, hạ lưu của bạn có thể tiếp tục sử dụng thư viện cũ cho đến khi chúng được chuyển đổi.
Monty Harder

@MontyHarder: Chắc chắn rồi. Chuỗi sự kiện chính xác có thể được xác định bởi nhu cầu của nhà phát triển và cộng đồng người dùng của họ. Tuy nhiên, điểm lớn hơn là cần có chính sách tư duy để xử lý các loại vấn đề phiên bản này được truyền đạt rõ ràng cho các bên liên quan.
Eric Lippert

24

Bạn đã hiểu nhầm "deprecated" nghĩa là gì. Phương tiện không dùng nữa:

có thể sử dụng được nhưng được coi là lỗi thời và tốt nhất nên tránh, điển hình là vì nó đã được thay thế.

Từ điển Oxford

Theo định nghĩa, một tính năng không dùng nữa sẽ vẫn được biên dịch.

Bạn đang tìm cách loại bỏ tính năng này vào một ngày cụ thể. Tốt rồi. Cách bạn làm là bạn loại bỏ nó vào ngày đó .

Cho đến lúc đó, đánh dấu là không tán thành, lỗi thời hoặc bất cứ điều gì ngôn ngữ lập trình của bạn gọi nó. Trong tin nhắn, bao gồm ngày nó sẽ bị xóa và thứ thay thế nó. Điều này sẽ tạo ra các cảnh báo, chỉ ra rằng các nhà phát triển khác nên tránh sử dụng mới và nên thay thế việc sử dụng cũ bất cứ khi nào có thể. Những nhà phát triển đó sẽ tuân thủ hoặc bỏ qua nó, và ai đó sẽ phải giải quyết hậu quả của điều đó khi nó bị xóa. (Tùy thuộc vào tình huống, có thể là bạn hoặc có thể là nhà phát triển sử dụng nó.)


Quan tâm đến những gì downvoter không đồng ý.
jpmc26

2
+1. Nếu bạn sử dụng JIRA để phát triển nhanh, hãy tạo một nhiệm vụ và đưa nó vào giai đoạn nước rút trong tương lai; thích ứng với bất kỳ công cụ và phương pháp quản lý dự án nào khác mà bạn tuân theo. Điều này được giải quyết tốt nhất với các phương pháp phi kỹ thuật.
Matthew Đọc

1
Và cũng đảm bảo rằng Class / Lib vẫn còn trong tài liệu là đã khấu hao và / hoặc bị xóa trong phiên bản Xx
Phil M

12

Đừng quên rằng bạn cần giữ lại khả năng xây dựng và gỡ lỗi các phiên bản mã cũ hơn để hỗ trợ các phiên bản phần mềm đã được phát hành. Phá hủy một bản dựng sau một ngày nhất định có nghĩa là bạn cũng có nguy cơ ngăn cản bản thân thực hiện công việc bảo trì và hỗ trợ hợp pháp trong tương lai.

Ngoài ra, có vẻ như một cách giải quyết tầm thường để đặt lại đồng hồ của máy tôi một hoặc hai năm trước khi biên dịch.

Hãy nhớ rằng, "không dùng nữa" là một cảnh báo rằng một cái gì đó sẽ biến mất trong tương lai. Khi bạn muốn ngăn chặn mọi người sử dụng API đó một cách mạnh mẽ, chỉ cần xóa mã liên quan . Không có điểm nào để lại mã trong cơ sở mã nếu một số cơ chế làm cho nó không sử dụng được. Xóa mã cung cấp cho bạn các kiểm tra thời gian biên dịch mà bạn đang tìm kiếm và không có cách giải quyết tầm thường.

Chỉnh sửa: Tôi thấy bạn đề cập đến "mã không sử dụng cũ" trong câu hỏi của bạn. Nếu mã thực sự không được sử dụng , sẽ không có điểm nào phản đối nó. Chỉ cần xóa nó.


Câu trả lời tốt nhất cho đến nay, có thể nhấn mạnh rằng xóa mã là cách tốt nhất để giải quyết vấn đề sớm hơn trong câu trả lời của bạn. Có thể dễ dàng cuộn qua tường câu trả lời văn bản
Clint

6

Tôi chưa bao giờ thấy một tính năng như vậy trước đây - một chú thích bắt đầu có hiệu lực sau một ngày cụ thể.

@Deprecatedthể là đủ, tuy nhiên. Nắm bắt các cảnh báo trong CI và làm cho nó từ chối chấp nhận bản dựng nếu có. Điều này chuyển trách nhiệm từ trình biên dịch sang đường ống xây dựng của bạn, nhưng có lợi thế là bạn có thể (bán) dễ dàng thay đổi đường ống xây dựng bằng cách thêm các bước bổ sung.

Lưu ý rằng câu trả lời này không giải quyết được hoàn toàn vấn đề của bạn (ví dụ: bản dựng cục bộ trên máy của nhà phát triển vẫn sẽ thành công, mặc dù có cảnh báo) và giả định rằng bạn có đường ống CI được thiết lập và chạy.


4

Bạn đang tìm kiếm lịch hoặc danh sách việc cần làm .

Một cách khác là sử dụng các cảnh báo trình biên dịch tùy chỉnh hoặc thông báo trình biên dịch, nếu bạn quản lý để có một vài cảnh báo trong cơ sở mã của bạn. Nếu bạn có quá nhiều cảnh báo, bạn sẽ cần tốn thêm công sức (khoảng 15 phút?) Và phải nhận cảnh báo trình biên dịch trong báo cáo bản dựng mà tích hợp liên tục của bạn cung cấp cho mỗi bản dựng.

Nhắc nhở rằng mã cần được sửa là tốt và cần thiết. Đôi khi những lời nhắc này có thời hạn thực tế nghiêm ngặt, vì vậy việc đặt chúng vào một bộ đếm thời gian cũng có thể cần thiết.

Mục tiêu là liên tục nhắc nhở mọi người rằng vấn đề tồn tại và cần được khắc phục trong một khung thời gian nhất định - một tính năng đơn giản phá vỡ bản dựng tại một thời điểm cụ thể không chỉ không làm điều đó, mà chính tính năng đó là vấn đề cần phải làm được cố định với một khung thời gian nhất định.


1
Đồng ý. Nhưng nếu một vấn đề tồn tại và cần được khắc phục trong một khung thời gian nhất định, thì nó cần phải trở thành ưu tiên hàng đầu của ai đó vào đúng thời điểm. Tôi nhớ khi trong một cuộc họp, Người quản lý của tôi đã dành cho tôi "ưu tiên hàng đầu", sau đó nói: " Đây là ưu tiên số một của bạn" (một cái gì đó khác biệt). Giám sát viên của tôi nói, "Anh ta không thể có hai ưu tiên số một!" Người quản lý giật mình. Tôi đoán anh ấy nghĩ rằng ... tôi có thể. Lập kế hoạch cho một cái gì đó để được sửa chữa "vào đúng thời điểm" đang lên kế hoạch hết thời gian.

3

Một cách để nghĩ về điều này là những gì bạn có nghĩa là theo thời gian / ngày ? Máy tính không biết những khái niệm này là gì: chúng phải được lập trình bằng cách nào đó. Nó khá phổ biến để biểu thị thời gian theo định dạng UNIX của "giây kể từ thời đại" và thông thường để cung cấp một giá trị cụ thể vào chương trình thông qua các cuộc gọi của hệ điều hành. Tuy nhiên, cho dù mức độ sử dụng phổ biến này như thế nào, điều quan trọng cần nhớ là đó không phải là thời gian "thực tế": nó chỉ là một biểu diễn logic.

Như những người khác đã chỉ ra, nếu bạn thực hiện một "thời hạn" bằng cách sử dụng cơ chế này, thì việc cho ăn trong một thời điểm khác và phá vỡ "thời hạn" đó là chuyện nhỏ. Điều tương tự cũng xảy ra đối với các cơ chế phức tạp hơn như yêu cầu máy chủ NTP (thậm chí qua kết nối "an toàn", vì chúng ta có thể thay thế chứng chỉ của chính mình, cơ quan cấp chứng chỉ hoặc thậm chí vá các thư viện tiền điện tử). Lúc đầu, có vẻ như các cá nhân đó có lỗi khi làm việc xung quanh cơ chế của bạn, nhưng có thể đó là trường hợp được thực hiện tự động và vì lý do chính đáng . Ví dụ: nên có các bản dựng có thể lặp lại và các công cụ để giúp việc này có thể tự động đặt lại / chặn các cuộc gọi hệ thống không xác định như vậy. libfaketime thực hiện chính xác điều đó,đặt tất cả dấu thời gian của tệp thành 1970-01-01 00:00:01, tính năng ghi / phát lại của Qemu làm giả mọi tương tác phần cứng, v.v.

Điều này tương tự như luật của Goodhart : nếu bạn thực hiện hành vi của chương trình phụ thuộc vào thời gian logic, thì thời gian logic sẽ không còn là thước đo tốt cho thời gian "thực tế". Nói cách khác, mọi người thường sẽ không gây rối với đồng hồ hệ thống, nhưng họ sẽ làm nếu bạn cho họ một lý do.

Có những cách biểu thị logic khác về thời gian: một trong số đó là phiên bản của phần mềm (ứng dụng của bạn hoặc một số phụ thuộc). Đây là một đại diện mong muốn cho "thời hạn" hơn là thời gian UNIX, vì nó cụ thể hơn với điều bạn quan tâm (thay đổi bộ tính năng / API) và do đó ít có khả năng chà đạp lên các mối quan tâm trực giao (ví dụ như thay đổi thời gian UNIX thành làm việc xung quanh thời hạn của bạn có thể sẽ phá vỡ các tệp nhật ký, công việc định kỳ, bộ nhớ cache, v.v.).

Như những người khác đã nói, nếu bạn kiểm soát thư viện và muốn "thúc đẩy" thay đổi này, bạn có thể đẩy một phiên bản mới làm mất tính năng (gây ra cảnh báo, để giúp người tiêu dùng tìm và cập nhật việc sử dụng), sau đó một phiên bản mới khác sẽ loại bỏ tính năng hoàn toàn. Bạn có thể xuất bản chúng ngay lập tức sau khi bạn thích, vì (một lần nữa) phiên bản chỉ là sự thể hiện logic của thời gian, chúng không cần phải liên quan đến thời gian "thực tế". Phiên bản ngữ nghĩa có thể giúp ở đây.

Mô hình thay thế là "kéo" sự thay đổi. Điều này giống như "kế hoạch B" của bạn: thêm một bài kiểm tra vào ứng dụng tiêu thụ, kiểm tra xem phiên bản của sự phụ thuộc này ít nhất là giá trị mới. Như thường lệ, red / green / refactor để truyền sự thay đổi này thông qua cơ sở mã. Điều này có thể phù hợp hơn nếu chức năng không "xấu" hoặc "sai", nhưng chỉ là "phù hợp xấu cho trường hợp sử dụng này".

Một câu hỏi quan trọng với phương pháp "kéo" là liệu phiên bản phụ thuộc có được tính là "đơn vị" ( của chức năng ) hay không, và do đó xứng đáng được thử nghiệm; hoặc cho dù đó chỉ là một chi tiết triển khai "riêng tư", chỉ nên được thực hiện như một phần của các bài kiểm tra đơn vị thực tế ( về chức năng ). Tôi muốn nói: nếu sự khác biệt giữa các phiên bản của phụ thuộc thực sự được tính là một tính năng của ứng dụng của bạn, thì hãy thực hiện kiểm tra (ví dụ: kiểm tra xem phiên bản Python có> = 3.x) không. Nếu không, thì đừngthêm bài kiểm tra (vì nó sẽ dễ vỡ, không chính xác và quá hạn chế); nếu bạn điều khiển thư viện thì đi xuống tuyến đường "đẩy". Nếu bạn không kiểm soát thư viện thì chỉ cần sử dụng bất kỳ phiên bản nào được cung cấp: nếu các bài kiểm tra của bạn vượt qua thì không đáng để tự giới hạn; nếu họ không vượt qua thì đó là "thời hạn" của bạn ngay tại đó!

Có một cách tiếp cận khác, nếu bạn muốn không khuyến khích sử dụng một số tính năng của phụ thuộc (ví dụ: gọi một số chức năng nhất định không hoạt động tốt với phần còn lại của mã), đặc biệt nếu bạn không kiểm soát phụ thuộc: cấm các tiêu chuẩn mã hóa của bạn / không khuyến khích việc sử dụng các tính năng này và thêm kiểm tra cho chúng cho kẻ nói dối của bạn.

Mỗi trong số này sẽ được áp dụng trong các trường hợp khác nhau.


1

Bạn quản lý này ở cấp độ gói hoặc thư viện. Bạn kiểm soát một gói và kiểm soát tầm nhìn của nó. Bạn được tự do rút lại tầm nhìn. Tôi đã thấy điều này trong nội bộ tại các công ty lớn và nó chỉ có ý nghĩa trong các nền văn hóa tôn trọng quyền sở hữu các gói ngay cả khi các gói là nguồn mở hoặc miễn phí sử dụng.

Điều này luôn luôn lộn xộn vì các nhóm khách hàng đơn giản là không muốn thay đổi bất cứ điều gì, vì vậy bạn thường cần một số vòng danh sách trắng - chỉ khi bạn làm việc với các khách hàng cụ thể để đồng ý về thời hạn di chuyển, có thể cung cấp hỗ trợ cho họ.


Tôi thích phần hỗ trợ. Tất cả các thay đổi diễn ra suôn sẻ hơn, dễ chịu hơn và có thể có ít khó khăn hơn nếu những người quảng bá chúng cung cấp hỗ trợ. Đó là một phần hiệu ứng tâm lý: Hỗ trợ tốt là hợp tác; tất cả liên quan nghiêm trọng. Ngược lại, những thay đổi áp đặt từ phía trên mà không liên quan đến những điều liên quan làm cho họ cảm thấy bị bỏ qua và không hợp tác. (Mặc dù sự thân thiện phải được kết hợp với một nỗ lực không ngừng để có được những thay đổi thông qua.)
Peter - Tái lập Monica

1

Một yêu cầu là đưa một khái niệm về thời gian vào bản dựng. Trong C, C ++ hoặc các ngôn ngữ / hệ thống xây dựng khác sử dụng bộ tiền xử lý giống như C 1 , người ta có thể đưa ra dấu thời gian thông qua định nghĩa cho bộ tiền xử lý tại thời điểm xây dựng : CPPFLAGS=-DTIMESTAMP()=$(date '+%s'). Điều này có thể sẽ xảy ra trong một makefile.

Trong mã người ta sẽ so sánh mã thông báo đó và gây ra lỗi nếu hết thời gian. Lưu ý rằng việc sử dụng macro chức năng sẽ bắt được trường hợp mà ai đó không xác định TIMESTAMP.

#if TIMESTAMP() == 0 || TIMESTAMP() > 1520616626
#   error "The time for this feature has run out, sorry"
#endif

Ngoài ra, người ta có thể chỉ cần "xác định" mã được đề cập khi thời gian đến. Điều đó sẽ cho phép chương trình biên dịch, miễn là không ai sử dụng nó. Giả sử, chúng tôi có một tiêu đề xác định một api, "api.h" và chúng tôi không cho phép gọi old()sau một thời gian nhất định:

//...
void new1();
void new2();
#if TIMESTAMP() < 1520616626
   void old();
#endif
//...

Một cấu trúc tương tự có thể sẽ loại bỏ phần old()thân của hàm khỏi một số tệp nguồn.

Tất nhiên đây không phải là bằng chứng ngu ngốc; người ta có thể chỉ cần định nghĩa một cái cũ TIMESTAMPtrong trường hợp xây dựng khẩn cấp tối thứ sáu được đề cập ở nơi khác. Nhưng đó là, tôi nghĩ, khá thuận lợi.

Điều này rõ ràng chỉ hoạt động khi thư viện được biên dịch lại - sau đó mã lỗi thời không còn tồn tại nữa trong thư viện. Nó sẽ không ngăn chặn mã máy khách liên kết đến các tệp nhị phân lỗi thời.


1 C # chỉ hỗ trợ định nghĩa đơn giản cho các ký hiệu tiền xử lý, không có giá trị số, điều này làm cho chiến lược này không khả thi.


Cũng cần lưu ý rằng bộ tiền xử lý này xác định sẽ buộc tất cả các mã sử dụng TIMESTAMPđược biên dịch lại trên mỗi bản dựng. Nó cũng sẽ vô hiệu hóa các công cụ như ccache. Điều này có nghĩa là thời gian biên dịch điển hình cho các bản dựng gia tăng sẽ tăng đáng kể tùy thuộc vào mức độ cơ sở mã bị ảnh hưởng bởi các tính năng không được dùng theo cách này.
mindriot

@mindriot Đó là một khía cạnh thú vị. Tôi cho rằng điều đó đúng với mọi phương pháp đưa ra một khái niệm về thời gian vào mã - OP đã nói rõ ràng "sau khi một ngày cụ thể đã trôi qua". Người ta có thể xử lý khía cạnh thời gian trong hệ thống xây dựng và để lại mã một mình, đúng. Nhưng OP đã hỏi rõ ràng về "một cái gì đó được đưa vào mã". Giải pháp của tôi có lợi thế là độc lập với bất kỳ phương pháp xây dựng cụ thể nào. Nó có thể bị lừa, nhưng bạn phải phục vụ nó bằng cách này hay cách khác.
Peter - Tái lập Monica

Bạn hoàn toàn đúng. Giải pháp của bạn ở đây về cơ bản là giải pháp duy nhất cung cấp giải pháp thực tế cho câu hỏi thực tế của OP . Tuy nhiên, tôi thấy điều quan trọng là chỉ ra nhược điểm. Sẽ tùy thuộc vào OP để cân nhắc những ưu và nhược điểm. Tôi nghĩ rằng một nền tảng trung bình lành mạnh thậm chí có thể đạt được bằng cách, chia TIMESTAMPgiá trị cho, giả sử, 86400, để có được độ chi tiết hàng ngày và do đó ít biên dịch lại.
mindriot

0

Trong Visual Studio, bạn có thể thiết lập một tập lệnh dựng sẵn gây ra lỗi sau một ngày nhất định. Điều này sẽ ngăn chặn việc biên dịch. Đây là tập lệnh đưa ra lỗi vào hoặc sau ngày 12 tháng 3 năm 2018 ( lấy từ đây ):

@ECHO OFF

SET CutOffDate=2018-03-12

REM These indexes assume %DATE% is in format:
REM   Abr MM/DD/YYYY - ex. Sun 01/25/2015
SET TodayYear=%DATE:~10,4%
SET TodayMonth=%DATE:~4,2%
SET TodayDay=%DATE:~7,2%

REM Construct today's date to be in the same format as the CutOffDate.
REM Since the format is a comparable string, it will evaluate date orders.
IF %TodayYear%-%TodayMonth%-%TodayDay% GTR %CutOffDate% (
    ECHO Today is after the cut-off date.
    REM throw an error to prevent compilation
    EXIT /B 2
) ELSE (
    ECHO Today is on or before the cut-off date.
)

Hãy chắc chắn đọc các câu trả lời khác trên trang này trước khi sử dụng tập lệnh này.


-1

Tôi hiểu mục tiêu của những gì bạn đang cố gắng làm. Nhưng như những người khác đã đề cập, hệ thống xây dựng / trình biên dịch có lẽ không phải là nơi thích hợp để thực thi điều này. Tôi muốn đề xuất lớp tự nhiên hơn để thực thi chính sách này là SCM hoặc biến môi trường.

Nếu bạn thực hiện sau, về cơ bản hãy thêm một cờ tính năng đánh dấu một lần chạy trước khấu hao. Mỗi khi bạn xây dựng lớp không dùng nữa hoặc gọi một phương thức không dùng nữa, hãy kiểm tra cờ tính năng. Chỉ cần xác định một hàm tĩnh duy nhất assertPreDeprecated()và thêm hàm này vào mọi đường dẫn mã không dùng nữa. Nếu nó được đặt, bỏ qua các cuộc gọi khẳng định. Nếu nó không ném vào một ngoại lệ. Khi ngày trôi qua, bỏ đặt cờ tính năng trong môi trường thời gian chạy. Bất kỳ cuộc gọi không được chấp nhận kéo dài tới mã sẽ hiển thị trong nhật ký thời gian chạy.

Đối với giải pháp dựa trên SCM, tôi sẽ cho rằng bạn đang sử dụng git và git-Flow. (Nếu không, logic có thể dễ dàng thích ứng với các VCS khác). Tạo một nhánh mới postDeprecated. Trong nhánh đó xóa tất cả các mã không dùng nữa và bắt đầu làm việc với bất kỳ tham chiếu nào cho đến khi nó biên dịch. Bất kỳ thay đổi bình thường tiếp tục thực hiện cho masterchi nhánh. Tiếp tục hợp nhất mọi thay đổi mã không liên quan mastertrở lại postDeprecatedđể giảm thiểu các thách thức tích hợp.

Sau khi ngày khấu hao kết thúc, tạo một preDeprecatedchi nhánh mới từ master. Sau đó hợp nhất postDeprecatedtrở lại vào master. Giả sử bản phát hành của bạn rời khỏi masterchi nhánh, bây giờ bạn sẽ sử dụng chi nhánh sau đó không dùng nữa sau ngày. Nếu có trường hợp khẩn cấp hoặc bạn không thể cung cấp kết quả kịp thời, bạn luôn có thể quay lại preDeprecatedvà thực hiện bất kỳ thay đổi cần thiết nào trên chi nhánh đó.


7
Cách tiếp cận đó nghe như một cơn ác mộng hậu cần. Nếu bạn bắt đầu duy trì các nhánh song song gần như trùng lặp, cuối cùng bạn sẽ dành toàn bộ thời gian để làm như vậy. Tổng chất thải.
Các cuộc đua nhẹ nhàng trong quỹ đạo

6
Tôi không thể đồng ý rằng việc duy trì các nhánh song song, sử dụng một nhánh đơn giản để loại bỏ các chức năng không dùng nữa trong nhiều phiên bản trước khi bạn thực sự muốn xóa chúng khỏi sản phẩm, theo bất kỳ cách nào là "tiêu chuẩn công nghiệp". Mục đích của điều đó là gì? Có, một VCS có thể tự động thực hiện một số hợp nhất, nhưng việc hợp nhất phải được thực hiện bằng mắt của nhà phát triển để giải quyết xung đột logic (và điều gì xảy ra khi bạn gặp phải một xung đột thậm chí không thể giải quyết bằng từ vựng?). Có một hệ thống xây dựng tùy ý hợp nhất mỗi ngày cho việc này chỉ là ... vô nghĩa. Xóa tính năng khi đến lúc xóa nó.
Các cuộc đua nhẹ nhàng trong quỹ đạo

3
Bởi vì có một lý do chính đáng để duy trì các nhánh phát hành (backporting các bản vá quan trọng). Không có lý do chính đáng để duy trì một chi nhánh "điều gì đó tôi có thể làm trong tương lai". Đó là chi phí, không có lợi. Đơn giản như thế.
Các cuộc đua nhẹ nhàng trong quỹ đạo

4
Tôi đã lấy nó ở đâu? Đó là nghĩa đen của sự phản đối. Bạn không tán thành một cái gì đó mà bạn có thể loại bỏ trong tương lai. Do đó, không có sự không tôn trọng, không di chuyển các bài viết mục tiêu và chắc chắn không làm cho mọi thứ chỉ là "để giành chiến thắng trong cuộc tranh luận". Đây không phải là "trường hợp sử dụng sách giáo khoa của phân nhánh SCM" trong bất kỳ tổ chức nào tôi muốn làm việc! Tôi đoán chúng ta sẽ phải đồng ý không đồng ý. Chúc buổi tối tốt lành!
Các cuộc đua nhẹ nhàng trong quỹ đạo

2
@lightness - Có nhiều lý do tại sao mã không chính thức không chỉ là "điều chúng ta có thể làm bất cứ khi nào chúng ta tiếp cận nó". Có thể mã không dùng nữa sử dụng thư viện, nơi hỗ trợ chính thức bị loại bỏ. Có thể mã không dùng nữa là IP mà giấy phép của họ sẽ hết hạn sau một ngày cố định. Có thể sau ngày nhất định, có các quy định mới và mã không tuân thủ. Giải pháp của bạn là tốt và tốt nếu bạn sống trong một tháp ngà. Nhưng orgs trong thế giới thực luôn luôn xử lý các loại tình huống này. Phần mềm cần thỏa mãn nhu cầu của doanh nghiệp chứ không phải ngược lại.
dùng79126
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.