|
|
|
Реализация Factory с Generic
|
|||
|---|---|---|---|
|
#18+
Добрый день, У меня есть иерархия объектов и иерархия обработчиков. Я пытаюсь сделать параметризованный Factory-метод и столкнулся со сложностями. В аттаче находится проект, иллюстрирующий проблему. Допустим, вот мои объекты: Код: java 1. 2. 3. 4. 5. А это мои обработчики: Код: java 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. Я хочу, чтобы мой factory-метод выглядел примерно вот так: Код: java 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. И чтобы его можно было использовать примерно так: Код: java 1. 2. 3. 4. Но последняя строка дает ошибку компиляции: Код: java 1. Вопросы: 1. Почему возникает эта ошибка? 2. Возможно ли добиться желаемого мной дизайна без explicit cast'ов? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 25.11.2013, 20:14:43 |
|
||
|
Реализация Factory с Generic
|
|||
|---|---|---|---|
|
#18+
abc_da, Ошибка возникает потому, что "?" в левой и правой части вашего метода не связаны. По сигнатурам вам нужно что-то вроде: Код: java 1. 2. 3. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.11.2013, 09:48:52 |
|
||
|
Реализация Factory с Generic
|
|||
|---|---|---|---|
|
#18+
тут сразу 2 ошибки. Код: java 1. 1) генерик на входе 2) на выходе генерик с неизвестным типом (даже ничем не параметризованный) Тема долгая, боюсь наделать ошибок, лучше обратиться к авторитетным книжкам Я бы предложил подход, используемый в шаблоне "посетитель". Заодно можно избежать многоэтажных if-конструкций: Код: java 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. ну и работа с этим: Код: java 1. 2. 3. 4. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.11.2013, 10:11:19 |
|
||
|
Реализация Factory с Generic
|
|||
|---|---|---|---|
|
#18+
Спасибо за ответы maxkar, так я тоже пробовал, но эффект такой же ivanra, спасибо, вы зрите в корень, мой следующий вопрос был бы "как избавиться от цепочки if-ов". К сожалению, предложенный вами вариант работает только если знать на момент компиляции, какого типа объект придет (как в моем упрощенном примере). Но в реальной жизни у меня нет такой информации, поэтому мне нужно разобраться с wildcard'ами, насколько я понимаю. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.11.2013, 11:41:26 |
|
||
|
Реализация Factory с Generic
|
|||
|---|---|---|---|
|
#18+
abc_da, так типизация как раз и предназначена для контроля типов на момент компиляции. Если у вас о конкретном типе становится известно только во время выполнения, то зачем все эти мучения? В этом случае интерфейс FruitHandler должен быть нетипизированным Код: java 1. 2. 3. Если же имеется в виду работа с классами - наследниками, то тут как раз все работает. Например, анонимный класс-наследник: Код: java 1. 2. 3. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.11.2013, 12:22:24 |
|
||
|
Реализация Factory с Generic
|
|||
|---|---|---|---|
|
#18+
abc_da, Код: java 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 26.11.2013, 12:28:30 |
|
||
|
Реализация Factory с Generic
|
|||
|---|---|---|---|
|
#18+
ivanra, Не согласен, на мой взгляд, FruitHandler должен быть типизированным, т.к. когда дело доходит до него, тип уже известен (если не использовать фабрику). Вероятно, фабричный метод должен иметь сигнатуру с нетипизированным возвращаемым FruitHandler (как предложил javapecker). Но я в принципе не понимаю, почему не получается сделать его типизированным через <? extends Fruit>. Почему new AppleHandler() приходится явно приводить к FruitHandler<T> ? И почему <T extends Fruit> и <? extends Fruit> - не одно и то же? Буду благодарен за ссылки на мат.часть. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 27.11.2013, 13:45:12 |
|
||
|
Реализация Factory с Generic
|
|||
|---|---|---|---|
|
#18+
Почему бы так не сделать? Понятно, что связность немного больше. Но в данном примере я вообще не вижу чему бы это мешало. Код: java 1. 2. 3. 4. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 27.11.2013, 13:53:09 |
|
||
|
Реализация Factory с Generic
|
|||
|---|---|---|---|
|
#18+
А ещё ошибка вот тут Код: java 1. Потому что по логике factory нужно Код: java 1. либо Код: java 1. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 27.11.2013, 14:00:56 |
|
||
|
Реализация Factory с Generic
|
|||
|---|---|---|---|
|
#18+
javapecker Код: java 1. 2. Unchecked assignment ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 27.11.2013, 14:04:22 |
|
||
|
Реализация Factory с Generic
|
|||
|---|---|---|---|
|
#18+
Точнее так. Без этого AppleHandler теряет информацию о любом наследнике Apple Код: java 1. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 27.11.2013, 14:07:59 |
|
||
|
Реализация Factory с Generic
|
|||
|---|---|---|---|
|
#18+
А ещё при явном конструировании какого-то Handler-а в Factory, обязательно нужно кастить, так как фабрика расчитана на более широкий даиапазон типов, и Generics не могут уже дать гарантий. Гарантии программист пишет явно в виде isAssignableFrom. Компилятор о них догадаться не может. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 27.11.2013, 14:12:03 |
|
||
|
Реализация Factory с Generic
|
|||
|---|---|---|---|
|
#18+
abc_da, типизация интерфейса FruitHandler приводит к необходимости явно знать всю информацию о типах во время компиляции, поэтому хорошо подумайте, нужна ли она. В яве наследование в генерике никак не учитывается, и тут ничего не поделаешь: Код: java 1. 2. 3. 4. Ваше стремление типизировать всё подряд приводит к сильной связанности кода, если фабрика возвращает что-то большее, чем FruitHandler<Fruit> Допустим, имеется: - изменяемая часть программы - набор классов-наследников Fruit, набор их обработчиков, фабрика - неизменяемая часть - некий бизнес код, использующий фабрику и то, что она производит Так вот, бизнес код у вас сейчас должен изменяться с изменяемой частью. Добавление любого нового класса/обработчкика ведет к его добавлению в бизнес-код. Так или иначе, там должно появиться что-то типа NewFruit, NewHandler, и даже Newhandler<NewFruit> По-любому плохо. Остается FruitHandler<Fruit>, а поскольку это масло масленное, то достаточно возвращать просто FruitHandler - так мы и пришли к выводу о лишней типизации интрфейса. Вы можете объяснить для чего она понадобилась? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 27.11.2013, 15:19:03 |
|
||
|
Реализация Factory с Generic
|
|||
|---|---|---|---|
|
#18+
ну просто хочется понять - в чем смысл? - используем генерики - хотим контролировать классы на этапе компиляции - используем фабрику (обычно это делается для манипулирования объектами на абстрактном уровне), то есть не хотим контролировать классы на этапе компиляции Единственный смысл, который я тут вижу - контроль котго, чтобы метод FruitHandler.handle возвращал объект того же типа, что и аргумент. так и следует типизировать сам метод Код: java 1. 2. 3. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 27.11.2013, 15:53:50 |
|
||
|
|

start [/forum/topic.php?fid=59&msg=38479856&tid=2128115]: |
0ms |
get settings: |
8ms |
get forum list: |
15ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
188ms |
get topic data: |
9ms |
get forum data: |
2ms |
get page messages: |
50ms |
get tp. blocked users: |
1ms |
| others: | 217ms |
| total: | 496ms |

| 0 / 0 |
