Как пометить класс как на стадии разработки в Java


12

Я работаю над проектом стажировки, но мне нужно уйти, прежде чем я смогу все закончить.

У меня есть 1 класс, который недостаточно стабилен для производственного использования. Я хочу отметить / пометить этот класс, чтобы другие люди не могли случайно использовать его в производстве. Я уже поместил уведомление в Javadoc, но этого недостаточно. Некоторые ошибки или предупреждения компилятора были бы лучше.

Код организован так:

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

Если бы был один фабричный класс, который вызывает эти классы в открытых методах, я мог бы установить метод class3как private. Однако API НЕ выставляется таким образом. Например new Class1();, пользователи будут напрямую использовать этот класс, но я не могу сделать класс верхнего уровня приватным. Как лучше всего справляться с этой ситуацией?


1
Что вы подразумеваете под "API не предоставляется через методы?" Этот класс предназначен для использования через Reflection API?
— Том Г

5
Ошибка компилятора? Почему бы просто не выбросить исключение в конструктор?
— Mchl

Извините за путаницу. Я отредактировал свой пост.
— Вэй Ши


1
Вы не можете сделать класс приватным, но вы можете сделать его конструктор приватным.
— Питер Тейлор

Ответы:


15

Почему бы просто не проверить все нестабильные классы в другой ветке в вашей системе контроля версий?


2
Мне кажется, что это «спрятало» код. Что делать, если код почти делает то, что нужно другим, чтобы сделать с некоторыми незначительными изменениями. Если вы поместите это в ветку, они никогда не увидят это и просто заново воплотят все это.
— c_maker

3
@c_maker: Сообщать другим, что ветвь существует, и то, что находится в ней, должно быть частью того, что передается, когда он уходит.
— Blrfl

2
@Birlf Если он обеспокоен тем, что другие не видят объяснения в JavaDoc кода, который они используют, я сомневаюсь, что они пойдут искать другую документацию, которую он создает.
— KeithB

Меня беспокоит то, что эта функция все еще развивается, но мастер Scrum решил отложить ее по любой причине (в нашем случае - мораторий, который блокирует тестирование E2E). Если мы не присоединимся к мастеру, возможно, в будущем будет много работы по слиянию. Мы просто сделали c'tor закрытым и аннотировали класс @Experimental, как в Spark
— Joey Baruch

11

Если вы правильно прокомментировали класс, вы можете пометить биты неполной функциональности как «устаревшие» и / или закомментировать внутренности метода и поставить a throw new UnsupportedOperationException();.

См. Есть ли что-нибудь вроде .NET NotImplementedException в Java? для деталей.


2
Это де-факто способ справиться с остроумием, как я понимаю вещи
— Мартейн Вербург

4

Я не знаю такого предупреждения компилятора.

В вашей ситуации я бы, вероятно, использовал @Deprecatedаннотацию. Он будет зачеркивать вызовы методов, поэтому другим будет очевидно, что что-то не так. Когда они посмотрят, что происходит, они увидят ваши комментарии о «не готов к производству» и пойдут AHA.


2
вызовы методов вычеркиваются, только если IDE поддерживает это.
— FrustratedWithFormsDesigner

5
Верно, но большинство людей, вероятно, будут использовать одну из тех IDE, которая поддерживает его.
— c_maker

3

Я не думаю , что есть стандартный способ маркировки коды , как WIP, Incompleteили что - то в этом роде.

Вы можете создать новое исключение с именем ClassUnstableExceptionи затем вызвать его в Class3конструкторе с сообщением, объясняющим, как им не следует его использовать. Это плохо, потому что он предупреждает их только во время выполнения.

Вы также можете попытаться сделать класс каким-то образом несовместимым, а затем добавить примечание в раздел кода, который отключает компилятор, чтобы, если кто-то попытается исправить код, он, надеюсь, увидит объяснение того, почему ему не следует использовать этот класс. , Это может не работать, если они используют полуавтоматический инструмент «исправить эту проблему», который есть в некоторых средах разработки. Это также плохо, потому что это может сломать сборки.

Вы можете создать аннотацию с именем WIP(поскольку я могу подумать, что это наиболее близко, Deprecatedно на самом деле это не означает то же самое) и использовать ее для аннотирования класса. Это, вероятно, будет немного больше работы, и что будет поддерживать аннотацию?

Наконец, вы можете просто добавить это в комментарии, но это сработает, только если люди действительно их прочитают .

РЕДАКТИРОВАТЬ:

Это может быть актуально: Как преднамеренно вызвать предупреждающее сообщение о компиляторе Java?


Исключение throw заставляет затмение жаловаться на недоступный код. Любое решение?
— Вэй Ши

@Usavich: Не уверен, так как я не видел код, но, может быть, это также поможет предотвратить использование кода будущими разработчиками ?
— FrustratedWithFormsDesigner

@Usavich: Посмотрите на ссылку, которую я добавил в своем редакторе в своем посте, это аналогичный вопрос, когда ОП хотел добавить предупреждение о компиляторе. Может помочь вам добавить пользовательскую аннотацию "UnstableCode".
— FrustratedWithFormsDesigner

3

Почему это там в первую очередь?

Вы проверили нестабильный код в магистрали? Почему?

Нестабильный код не должен быть зарегистрирован в trunk / main / master или как там есть основное имя транка. Это считается разработкой с высоким уровнем риска, и вместо этого она должна была быть изолирована в своей собственной ветке, над которой вы работали, а не проверена на main.

Я настоятельно рекомендую вам (и руководителю вашей команды) прочитать Расширенные стратегии ветвления SCM . В частности, обратите внимание на роль разработки и то, что в ней говорится о том, что считается развитием высокого риска:

В общем, рассмотрите возможность использования отдельных веток для каждого проекта с высокой степенью риска. Проекты с высоким риском характеризуются большим размером, большим количеством людей, незнакомыми предметами, высокотехнологичными предметами, очень жесткими временными рамками, неопределенными сроками сдачи, неполными или нестабильными требованиями и географически распределенными проектными командами. Точно так же рассмотрите возможность назначения отдельной ветки для разработки с низким уровнем риска в каждом выпуске. Несколько источников, включая [WING98], рекомендуют использовать магистраль для этой цели. Рассмотрите факторы, обсужденные выше для основной линии, прежде чем совершать этот курс действий. Разработка с низким уровнем риска может отличаться от основной линии, даже если у вас есть несколько членов семейства продуктов, координирующих через основную линию.

Разрешение людям проверять нестабильный (или неиспользуемый) код в основной строке означает, что вы будете путать будущие усилия по разработке с попыткой сохранить этот код. Каждая ветвь и клон представителя с этого момента до конца времени будут содержать это, пока кто-нибудь не скажет «его мертвый код» и не удалит его.

Некоторые говорят, что «хорошо, если в ветке это забыто», и хотя это может быть правдой, забыть мертвый (и нестабильный) код в mainline во много раз хуже, так как он запутывает всю будущую разработку, пока он не будет удален - и тогда это еще более забыто. Красиво названная ветка "/ fooProject / branch / WeisBigIdea" (или эквивалентная) видна и с ней легче работать в будущем - особенно, если она работает.

@Deprecated

Первое - это @Deprecatedаннотация. Это выходит за рамки javadoc и выдает предупреждения компилятора. javacпредоставляет -deprecationфлаг, который описывается как:

Показать описание каждого использования или переопределения устаревшего члена или класса. Без -deprecation, javacпоказывает сводку исходных файлов, которые используют или переопределяют устаревшие элементы или классы. -декрекция это сокращение от -Xlint:deprecation.

Как уже отмечалось, это выходит за рамки стандартных предупреждений компилятора.

Во многих средах разработки устаревшие методы и значения показаны зачеркнутыми:

foo.bar();

И будет производить вывод, как:

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

В зависимости от вашей структуры сборки, у вас могут быть предупреждения, нарушающие сборку. Это нарушит сборку только в том случае, если будет использован один из ваших классов (а не если он просто скомпилирован).

@CustomAnnotation

Есть много подходов к этому. Например, облегченная аннотация javac @Warning, которая предоставляет процессор аннотаций, который выдает предупреждение во время компиляции, когда используется что-то с этой аннотацией ( учебное руководство по netbeans на пользовательских процессорах аннотаций, чтобы вы могли получить представление о том, что происходит за сцены).

Oracle даже описывает пример использования пользовательских аннотаций для @Unfinishedаннотации в статье Использование большинства метаданных Java, часть 2: Пользовательские аннотации .

С AnnotationProcessor вы можете запускать произвольный код во время компиляции. Вам решать, что вы хотите от этого. Предупредить, сломать сборку, когда что-то используется. В Интернете существует множество учебных пособий по написанию такого рода кода. Если вы хотите сгенерировать ошибку при ее компиляции (это будет раздражать и привести к ее удалению), или если ее использовать (написать немного сложнее).

Обратите внимание, что все это подразумевает изменение сборок для фактического использования процессора аннотаций.


2

Вы можете ввести обработку аннотаций времени компиляции, но это заставит всех членов команды корректировать процесс компиляции.

Однако я нахожу весь процесс немного запутанным. Нестабильный API должен быть четко отделен путем создания ветки в вашей системе контроля версий. Если он действительно должен быть в остальной части кодовой базы, был задокументирован как нестабильный и, тем не менее, используется, проблема не является на самом деле технической, а лежит внутри организации и коммуникации. Да, вы можете ввести технические проверки (например, обработку аннотаций), но это не решит проблему - просто переместите ее на другой уровень.

Поэтому я рекомендую: если вы не можете разделить кодовую базу, поместив ее в разные ветви, поговорите с людьми и объясните им, почему они не должны использовать API.


0

Не могли бы вы переместить все неполные классы в подпакет с именем что-то очевидное, например "NOTCOMPLETE"? Это что-то вроде хака, но может быть достаточно заметным.

(Если они не все в одном пакете, вы можете воссоздать структуру пакета там.)


0

Я не знаю, что есть действительно хороший способ сделать это в коде. Сделать шаг назад:

Создайте две копии всего проекта, один с классом, а другой без. Отметьте версию без класса как стабильную кодовую базу, готовую к производственному выпуску, а версию с классом как разработку для будущего выпуска. Документируйте, что должно произойти, прежде чем этот класс можно будет считать производственным качеством.

В идеале вы должны делать это с помощью веток в выбранном вами решении управления исходным кодом. Возможно, вам придется немного обмануть, поскольку, похоже, вы не использовали такую ​​стратегию ветвления. Осторожно удалите новый класс, зарегистрируйте версию без него и проведите регрессивное тестирование. Когда вы убедитесь, что она стабильна, вы можете пометить эту ревизию, создать ветку разработки из тега, а затем добавить класс обратно в ветку разработки.


0

Я бы предпочел сделать класс абстрактным и правильно прокомментировать - таким образом, код все еще там для справки, но удачи всем, кто пытается его реализовать :)


-1

Как насчет создания зависимости, которую компилятор не может разрешить? Просто добавь:

импортировать this.is.not.done.yet.do.not.use.it;

наверх Пользователи не смогут скомпилировать его.

Если вы хотите протестировать класс, просто создайте пакет / класс с этим именем (или используйте более простой, например, «Экспериментальный. Опасный»), и вы можете протестировать новый код.


1
Компиляция не удастся, даже если я ее не использую ... плохая идея ...
— Сильвиу Бурча
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.