Cách gắn cờ một lớp như đang phát triển trong Java


12

Tôi đang làm việc trong một dự án thực tập, nhưng tôi phải rời đi trước khi tôi có thể hoàn thành mọi thứ.

Tôi có 1 lớp không đủ ổn định để sử dụng sản xuất. Tôi muốn đánh dấu / gắn cờ lớp này để người khác không vô tình sử dụng nó trong sản xuất. Tôi đã đặt thông báo trong Javadoc, nhưng điều đó dường như không đủ. Một số lỗi biên dịch hoặc cảnh báo sẽ tốt hơn.

Mã được tổ chức như thế này:

[Package] | company.foo.bar.myproject
          |-- Class1.java
          |-- Class2.java
          |-- Class3.java <--(not stable)

Nếu có một lớp nhà máy duy nhất mà các cuộc gọi những lớp học trong phương pháp nào, tôi có thể đã thiết lập phương pháp để class3làm private. Tuy nhiên, API KHÔNG được hiển thị theo cách đó. Người dùng sẽ trực tiếp sử dụng các lớp đó, ví dụ new Class1();, nhưng tôi không thể đặt lớp riêng ở cấp cao nhất. Cách thực hành tốt nhất để đối phó với tình huống này là gì?


1
Ý bạn là gì khi "API không được hiển thị thông qua các phương thức?" Lớp này có được sử dụng thông qua API Reflection không?
Tom G

5
Một lỗi biên dịch? Tại sao không ném một ngoại lệ trong constructor?
Mchl

Xin lỗi vì sự nhầm lẫn. Tôi đã chỉnh sửa bài viết của mình.
Wei Shi


1
Bạn không thể đặt lớp riêng tư, nhưng bạn có thể đặt lớp xây dựng riêng tư.
Peter Taylor

Câu trả lời:


15

Tại sao không kiểm tra tất cả các lớp không ổn định thành một nhánh khác trên hệ thống kiểm soát phiên bản của bạn?


2
Dường như với tôi rằng điều này sẽ 'ẩn' mã. Điều gì sẽ xảy ra nếu mã gần như làm những gì người khác cần nó để làm với một số điều chỉnh nhỏ. Nếu bạn đặt nó trong một nhánh, họ có thể không bao giờ nhìn thấy nó và sẽ chỉ thực hiện lại toàn bộ.
c_maker

3
@c_maker: Cho người khác biết chi nhánh tồn tại và những gì trong đó sẽ là một phần của những gì được truyền lại khi anh ta rời đi.
Blrfl

2
@Birlf Nếu anh ấy lo lắng về việc người khác không thấy lời giải thích trong mã JavaDoc mà họ đang sử dụng, tôi nghi ngờ rằng họ sẽ đi tìm tài liệu khác mà anh ấy tạo ra.
KeithB

Mối quan tâm của tôi là tính năng này vẫn đang phát triển, nhưng chủ scrum đã chọn đặt nó sang một bên vì bất kỳ lý do gì (lệnh cấm chặn thử nghiệm E2E, trong trường hợp của chúng tôi). Nếu chúng ta không tham gia nó để thành thạo, có thể có rất nhiều công việc hợp nhất trên đường. Chúng tôi chỉ làm cho c`tor riêng tư và chú thích lớp @Experimental, như trong Spark
joey baruch

11

Nếu bạn đã nhận xét đúng về lớp, bạn có thể đánh dấu các bit của chức năng không đầy đủ là "không dùng nữa" và hoặc nhận xét sự can đảm của phương thức và đặt a throw new UnsupportedOperationException();.

Xem Có bất cứ điều gì như .NET 'NotImcellenceedException trong Java không? để biết chi tiết.


2
Đây là cách xử lý không chính xác khi tôi hiểu mọi thứ
Martijn Verburg

4

Tôi không biết cảnh báo trình biên dịch như vậy.

Trong tình huống của bạn, tôi có thể sẽ sử dụng @Deprecatedchú thích. Nó sẽ gạch bỏ các cuộc gọi phương thức, vì vậy sẽ rõ ràng với những người khác rằng có gì đó đang xảy ra. Khi họ xem xét vấn đề, họ sẽ thấy nhận xét của bạn về 'không sẵn sàng sản xuất' và đi AHA.


2
các cuộc gọi phương thức chỉ bị gạch bỏ nếu IDE hỗ trợ nó.
Thất vọngWithFormsDesigner

4
Đúng, nhưng hầu hết mọi người có thể sẽ sử dụng một trong những IDE hỗ trợ nó.
c_maker

3

Tôi không nghĩ rằng có một cách tiêu chuẩn đánh dấu mã như WIP, Incompletehoặc một cái gì đó như thế.

Bạn có thể tạo một ngoại lệ mới có tên ClassUnstableExceptionvà sau đó nâng nó trong hàm Class3tạo với một thông báo giải thích cách họ không nên sử dụng nó. Điều này là xấu mặc dù, bởi vì nó chỉ cảnh báo họ trong thời gian chạy.

Bạn cũng có thể thử làm cho lớp không thể hoàn thành theo một cách nào đó, sau đó thêm một ghi chú vào phần mã làm vấp trình biên dịch để nếu ai đó đi sửa mã, họ sẽ hy vọng thấy được lời giải thích tại sao họ không nên sử dụng lớp đó . Điều này có thể không hoạt động nếu họ sử dụng một số công cụ "khắc phục sự cố" bán tự động mà một số IDE có. Điều này cũng xấu vì nó có thể phá vỡ các bản dựng.

Bạn có thể tạo một chú thích có tên WIP(vì gần nhất tôi có thể nghĩ là Deprecatednhưng nó không thực sự có nghĩa tương tự) và sử dụng nó để chú thích lớp. Đây có lẽ sẽ là một công việc nhiều hơn một chút, và những gì sẽ hỗ trợ chú thích?

Cuối cùng, bạn chỉ có thể đưa nó vào các bình luận, nhưng điều đó sẽ chỉ hoạt động nếu mọi người thực sự đọc chúng.

BIÊN TẬP:

Điều này có thể có liên quan: Làm thế nào để cố ý gây ra một thông báo cảnh báo trình biên dịch java tùy chỉnh?


ngoại lệ ném làm cho nhật thực phàn nàn về mã không thể truy cập. Bất kỳ cách giải quyết?
Wei Shi

@Usavich: Không chắc vì tôi chưa thấy mã, nhưng có lẽ điều đó cũng có thể giúp ngăn các nhà phát triển trong tương lai sử dụng mã?
Thất vọngWithFormsDesigner

@Usavich: Hãy xem liên kết tôi đã thêm trong EDIT trong bài đăng của mình, đây là một câu hỏi tương tự trong đó OP muốn thêm cảnh báo trình biên dịch tùy chỉnh. Có thể giúp bạn thêm một chú thích "UnurdyCode" tùy chỉnh.
Thất vọngWithFormsDesigner

2

Bạn có thể giới thiệu xử lý chú thích thời gian biên dịch nhưng điều này sẽ buộc tất cả các thành viên trong nhóm điều chỉnh quy trình biên dịch của họ.

Tuy nhiên tôi thấy toàn bộ quá trình hơi khó hiểu. Một API không ổn định cần được phân tách rõ ràng bằng cách tạo một nhánh trong hệ thống kiểm soát phiên bản của bạn. Nếu nó thực sự phải nằm trong phần còn lại của codebase, đã được ghi nhận là không ổn định và tuy nhiên được sử dụng thì vấn đề không thực sự là kỹ thuật mà nằm trong tổ chức và giao tiếp. Có, bạn có thể giới thiệu các xác minh kỹ thuật (như xử lý chú thích) nhưng điều đó sẽ không giải quyết được vấn đề - chỉ cần chuyển nó sang một cấp độ khác.

Vì vậy, khuyến nghị của tôi là: Nếu bạn không thể tách cơ sở mã bằng cách đặt nó vào các nhánh khác nhau thì hãy nói chuyện với mọi người và giải thích cho họ tại sao họ không được sử dụng API.


2

Tại sao nó ở đó ngay từ đầu?

Bạn đã kiểm tra mã không ổn định vào dòng chính? Tại sao?

Mã không ổn định không nên được kiểm tra vào thân / chính / chính hoặc bất kỳ tên thân chính là gì. Đây được coi là sự phát triển rủi ro cao và thay vào đó nên được cách ly trong nhánh riêng của nó mà bạn đã làm việc thay vì kiểm tra chính.

Tôi đặc biệt khuyến khích bạn (và nhóm trưởng của bạn) đọc Chiến lược phân nhánh SCM nâng cao . Cụ thể, chú ý đến vai trò phát triển và những gì nó nói về những gì được coi là phát triển rủi ro cao:

Nói chung, xem xét sử dụng các chi nhánh riêng biệt cho từng dự án rủi ro cao. Các dự án rủi ro cao được đặc trưng bởi quy mô lớn, số lượng người lớn, chủ đề xa lạ, chủ đề kỹ thuật cao, dòng thời gian rất chặt chẽ, ngày giao hàng không chắc chắn, yêu cầu không đầy đủ hoặc không ổn định và các nhóm dự án phân phối theo địa lý. Tương tự, hãy xem xét chỉ định một nhánh duy nhất để phát triển rủi ro thấp trong mỗi bản phát hành. Một số nguồn bao gồm [WING98] khuyên bạn nên sử dụng đường dây chính cho mục đích này. Hãy xem xét các yếu tố được thảo luận ở trên cho tuyến chính trước khi cam kết thực hiện hành động này. Phát triển rủi ro thấp có thể có chính sách khác với tuyến chính ngay cả khi bạn có nhiều thành viên trong một gia đình sản phẩm điều phối thông qua tuyến chính.

Để mọi người kiểm tra mã không ổn định (hoặc không sử dụng) vào dòng chính có nghĩa là bạn sẽ nhầm lẫn giữa các nỗ lực phát triển trong tương lai về việc cố gắng duy trì mã này. Mỗi nhánh và bản sao của đại diện từ giờ cho đến hết thời gian sẽ chứa thứ này cho đến khi ai đó nói "codE chết" của nó và xóa nó.

Có một số người nói rằng "tốt, nếu nó ở trong một nhánh thì nó bị lãng quên" và trong khi đó có thể là sự thật, việc quên mã chết (và không ổn định) trong dòng chính tệ hơn nhiều lần vì nó gây nhầm lẫn cho tất cả sự phát triển trong tương lai cho đến khi nó bị xóa - và sau đó nó thậm chí còn bị lãng quên nhiều hơn Một nhánh được đặt tên độc đáo của "/ fooProject / cành / WeisBigIdea" (hoặc tương đương) có thể nhìn thấy và dễ dàng hoạt động hơn trong tương lai - đặc biệt nếu đó là loại công việc.

@Deprecated

Điều đầu tiên là @Deprecatedchú thích. Điều này vượt ra ngoài javadoc và đưa ra các cảnh báo về trình biên dịch. javaccung cấp một -deprecationcờ được mô tả là:

Hiển thị một mô tả về mỗi lần sử dụng hoặc ghi đè của một thành viên hoặc lớp không dùng nữa. Không có -deprecation, javachiển thị một bản tóm tắt các tệp nguồn sử dụng hoặc ghi đè các thành viên hoặc lớp không dùng nữa. -deprecation là tốc ký cho -Xlint:deprecation.

Như đã lưu ý, điều này vượt lên trên và vượt ra ngoài các cảnh báo của trình biên dịch tiêu chuẩn.

Trong nhiều IDE, các phương thức và giá trị không dùng nữa được hiển thị với một gạch ngang:

foo.bar();

Và sẽ tạo ra sản lượng như:

$ javac -Xlint:all Foo.java Bar.java
Bar.java:2: warning: [deprecation] Foo in unnamed package has been deprecated
interface Bar extends Foo { }
                      ^

Tùy thuộc vào cấu trúc bản dựng của bạn, bạn có thể có các cảnh báo phá vỡ bản dựng. Điều này sẽ chỉ phá vỡ bản dựng nếu một trong các lớp của bạn được sử dụng (không phải nếu nó chỉ được biên dịch đơn giản).

@CustomAnnotation

Có nhiều cách tiếp cận này. Ví dụ: chú thích javac @Warning nhẹ cung cấp bộ xử lý chú thích sẽ đưa ra cảnh báo vào thời gian biên dịch khi sử dụng một chú thích với chú thích đó ( hướng dẫn của netbeans về bộ xử lý chú thích tùy chỉnh để bạn có thể biết được những gì đang diễn ra đằng sau cảnh).

Oracle thậm chí còn mô tả một ví dụ về việc sử dụng các chú thích tùy chỉnh cho một @Unfinishedchú thích trong việc tận dụng tối đa siêu dữ liệu của Java, Phần 2: Chú thích tùy chỉnh .

Với AnnotationProcessor , bạn có thể chạy mã tùy ý tại thời gian biên dịch. Nó thực sự tùy thuộc vào bạn để quyết định những gì bạn muốn nó làm. Cảnh báo, phá vỡ các bản dựng khi một cái gì đó được sử dụng. Có rất nhiều hướng dẫn trên mạng về cách viết loại mã này. Cho dù bạn muốn tạo ra một lỗi khi nó được biên dịch (điều này sẽ gây khó chịu và dẫn đến việc nó bị xóa) hoặc nếu nó được sử dụng (khá phức tạp hơn một chút để viết).

Lưu ý rằng tất cả điều này ngụ ý việc thay đổi các bản dựng để thực sự sử dụng bộ xử lý chú thích.


0

Bạn có thể chuyển tất cả các lớp không hoàn chỉnh thành một gói con có tên rõ ràng như "KHÔNG HOÀN THÀNH" không? Đó là một chút hack nhưng có thể nhìn thấy đủ.

(Nếu chúng không phải là tất cả trong cùng một gói, bạn có thể tạo lại cấu trúc gói bên dưới.)


0

Tôi không biết rằng thực sự có một cách tốt để làm điều này trong mã. Lùi lại một bước:

Tạo hai bản sao của toàn bộ dự án, một bản có lớp và một bản không có. Đánh dấu phiên bản không có lớp là một cơ sở mã ổn định, sẵn sàng để phát hành sản xuất và phiên bản với lớp là sự phát triển cho phiên bản tương lai. Tài liệu những gì cần phải xảy ra trước khi lớp này có thể được coi là chất lượng sản xuất.

Tốt nhất, bạn nên làm điều này bằng cách sử dụng các nhánh trong giải pháp kiểm soát nguồn của bạn. Bạn có thể phải gian lận một chút, vì có vẻ như bạn chưa sử dụng chiến lược phân nhánh như vậy. Cẩn thận loại bỏ lớp mới, kiểm tra phiên bản không có nó và thực hiện một số thử nghiệm hồi quy. Khi bạn hài lòng, nó ổn định, bạn có thể gắn thẻ sửa đổi đó, tạo nhánh phát triển từ thẻ và sau đó thêm lớp trở lại trong nhánh phát triển.


0

Tôi đã chọn để làm cho lớp trừu tượng và nhận xét một cách thích hợp - theo cách đó, mã vẫn ở đó để tham khảo, nhưng chúc may mắn cho bất cứ ai cố gắng khởi tạo nó :)


-1

Điều gì về việc tạo một phụ thuộc mà trình biên dịch không thể giải quyết? Chỉ cần thêm:

nhập cái này.is.not.done.yet.do.not.use.it;

đầu trang. Người dùng sẽ không thể biên dịch với nó.

Nếu bạn muốn kiểm tra lớp, chỉ cần tạo một gói / lớp có tên đó (hoặc sử dụng một gói đơn giản hơn như "thử nghiệm.danger") và bạn có thể kiểm tra mã mới.


1
Trình biên dịch sẽ thất bại ngay cả khi tôi không sử dụng nó ... ý tưởng tồi ...
Silviu Burcea
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.