Как пометить класс как на стадии разработки в 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.