Comments 15

Прекрасная замена @Overrides. Только я бы назвал анноташку "Implements", чтобы естественнее читалась

Ага, написать Implement как съесть печеньку и не запить чайком, вроде и вкусно, но чего-то не хватает. Но и существующая аннотация Override и совпадение имени аннотации с ключевым слово языка немного режет глаз.
RotateCounter не может знать о том, свободен ли выбранный id

эммм… а можно поинтересоваться откуда столько смелости просто выкинуть принцип инкапсуляции и размазать знания о функционале по всему проекту?
как раз класс, занимающийся идентификаторами и должен заниматься проверками их валидности.


вообще статья мне понравилась, но работать с таким я откровенно не хотел бы)
во-первых, использование SOF должно сводиться к минимуму. не потому что там легко найти ответы (чтение документации полезнее списывания), а потому что можно перетащить чужие ошибки.
во-вторых, если я возьму этот проект и запущу его в другой IDE или даже просто другом eclipse — оно работать будет? не уверен… но если будет — это потрясающе.
ну и чисто эстетическое замечание — reflection- методы являются проктологией в Java. обычно их приплетают либо если все совсем плохо(сторонняя библиотека с приватными доступами etc), либо где-то в архитектуре ошибка. с точки зрения практики — задача интересная. но для поддержки неприменимо.


Как я понимаю изначально проблема пришла из невозможности понять откуда взялся метод.
JavaDoc тогда уж в помощь. Ну или пользуйтесь горячими клавишами вроде "перейти к родителю".


/**
* {@link ru.ohotnik.lab.SomeClass#myMethod(String, String)}   - ссылка на метод. в IDEA  доступна для перехода по клику. другие IDE думаю не хуже
* {@link ru.ohotNik.lab.SomeClass} - ссылка на класс ...
*/

Дело в том, что я так и не смог найти способ получить фактические параметры типов которым для обобщенных интерфейсы.

небольшая опечатка. не совсем понял что не получилось.

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

Я думаю, что не метод, а пачка методов. В классе десяток-другой методов происхождением из различных интерфейсов. Хочется, не тыкаясь в каждый метод по отдельности, глазами созерцать какие методы из каких интерфейсов пришли. Мне лично это знакомо.
Спасибо за такой развернутый комментарий.

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

Дальше сложнее. Честно говоря, я не знаю что такое SOF (и гугл выдает нечто вроде Special Operations Force).

Eclipse-проект нельзя просто так взять и запустить в другой IDE. А в другом Eclipse без проблем. К тому же, в коде или сборке .jar нет ничего eclipse-специфического. Как будет время надо будет сделать через gradle.

Про reflection тоже не понятно. Это же не рефлексия. Рефлексия это получение информации о типе на этапе выполнения. А это обработка на этапе компиляции.

Про JavaDoc согласен. Это красиво и без танцев с бубном. Но огорчает, что в C# эта возможность встроена в язык, а в Java нет.

За опечатку отдельное спасибо. Я отредактировал тот абзац и постарался пояснить подробнее. Если не трудно, глянь, пожалуйста, абзац, стало ли понятнее?
Про инкапсуляцию не согласен. Валидность идентификатора зависит от внутренней реализации UnitManagerа и RotateCounter, который, кстати, я и использую в нескольких местах, ничего не должен знать об ее особенностях.

напрашивается паттерн фабрики.
вы указываете тип нужного идентификатора (строка, число, UUID, полоски зебры), отдельно указывается алгоритм проверки, что идентификатор свободен.
После этого любой из кирпичиков свободно вынимается и заменяется на аналог.
Но если так уж нужно иметь средство проверки именно в UnitManager… Если так?


interface KeyValidable<T> {
  boolean validateKey(T key);
}

class UnitManager implements KeyValidable<Long> {
   ...
   boolean validateKey(Long key) {
       //здесь некоторая логика
   }
}

не вгонял в компилятор, но суть примерно такая.
хотя мы углубляемся уже в евангелистику)


SOF — это Stackoverflow. тут опять же спор вечен. я лично больше люблю работать с ребятами, которые могут решить проблему разобравшись в ней по исходникам. Доходит до обращений к исходникам Jdk. Не могу утверждать, что готовый ответ плохо. При дефиците времени это даже спасает. Но ведь потратите вы час на изучение исходников или минуту на копирование строки — что запомнится?)


Eclipse-проект нельзя просто так взять и запустить в другой IDE.

ну вообще можно. но только предварительно установить специальный плагин нужно и в 90-95 процентах случаев все заведется)


Рефлексия это получение информации о типе на этапе выполнения. А это обработка на этапе компиляции.

У вас на этапе компиляции работает программа. Пусть и процессор. Все равно процесс есть.
Но частично согласен — это скорее из сферы плагинов и т.п.
Да и те же постпроцессоры спринга на рефлексию завязаны не слабо. А уж там ребята явно очень долго думали как бы обойтись без этого. И как видно не придумали.


При анализе метода в классе, тип параметра String, а в интерфейсе — T, и все попытки получить вместо него String не к чему не привели.

о! эта задача интересна) так просто не обходится.
возможно эта статья натолкнет на решение?

вы указываете тип нужного идентификатора (строка, число, UUID, полоски зебры), отдельно указывается алгоритм проверки, что идентификатор свободен.
Будь алгоритм проверки чуть сложнее (хотя бы 3 строки), я бы, наверное, так и сделал.

А на Stackoverflow иногда бывают очень хорошие решения, но очень редко их можно использовать как есть, в основном приходится еще дополнительно подпиливать. Так что копипаст меня вряд ли поглотит)

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

Рефлексия это да, иногда сильно упрощает жизнь, но если решил использовать подумай, может не все таки стоит)

За статью спасибо, почитаю на досуге.

IMHO, в Java реализация объектом дополнительных интерфейсов, не определяющих его (объекта) основную функцию, является спорной практикой и сама по себе усложняет понимание структуры. Лучше действительно вынести реализации этих интерфейсов в функции-геттеры, пусть это и добавит пару строк кода.


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


К примеру, если у вас есть некий интерфейс Magic с функцией getValue(), который вы планируете реализовывать как добавочный, то функцию лучше назвать не getValue(), а getMagicValue(), чтобы не путаться при чтении и не бояться конфликта имён.

Дело в вкуса. Лично мне не нравится плодить дополнительные объекты, они меня запутывают еще больше.

Про getMagicValue() согласен, раньше именно так и делал. Но наличие аннотации над методом уже говорит, что он не простой. Слово класс, уверен, подсвечивается всеми IDE как ключевое слово языка. Все это позволяет понять, что метод для реализации интерфейса даже не читая его названия!

Тут кроме вкусовщины есть ещё как минимум две на мой взгляд важных детали.


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


2) Аннотации никак не уберегут Вас от конфликта имён, когда Вам придётся реализовывать два интерфейса с одноимёнными методами ) Даже получив нормальную диагностику об ошибке, придётся пересматривать именование методов.

какая часть хранимого состояния объекта используется для реализации каждого интерфейса.
Вообще да. Но если такое состояние является частью основной логики класса то не вижу в его хранении ничего страшного. А когда начнутся трудности с пониманием то я таки воспользуюсь вашим советом и вынесу реализации интерфейсов в отдельные классы.

Аннотации никак не уберегут Вас от конфликта имён
Согласен на 100%, но эти ситуации довольно редкие.
А пример в конце раздела «Постановка задачи» не подходит? Там в классе UnitManager есть метод isValueFree() помеченный @Implements. Или я неправильно понял о каком примере идет речь?
Only those users with full accounts are able to leave comments. Log in, please.