Comments 17
Если мы говорим о библиотеках, то их код пишет (условно) один разработчик, а читают тысячи. Поэтому экономить на бойлерплейте в ущерб читаемости, скрывая магию за какими-то методами, вызываемыми через рефлексию - очень такое себе.
Если же мы говорим о приложении, то даже в этом случае код может читаться значительно больше времени чем было потрачено на написание. Ну и для приложения есть DI-контейнер с аннотацями Inject, Autowired и т.п., которые являются стандартом, то есть не вызовут лишнего WTF при чтении кода.
Зачем читать передачу / получение зависимостей? Нужно ли это? В ваших интерфейсах будет описано, какие зависимости они могут иметь. И кто читает библиотеки? 1% мейнтейнеров? Библиотеки не читают а устанавливают. Еще раз повторюсь, видеть как передается определенный параметр может и нужно, зачем видеть передачу зависимостей и что может быть такого ужасного если ее не прочитают, я не знаю.
Ну вот я ни разу не ментейнер спринга. Однако спрингового кода (именно фреймворка) прочитал более чем достаточно, потому как не всегда документация дает четкий ответ "как это работает?" и "откуда вылез этот баг?". В идеальном мире, разумеется, есть идеальная документация, но в реальном мире разработчики приложений еще как читают код библиотек и фреймворков.
Какие универсалии? Всё описанное называется примесями (mixins, traits).
Идея, конечно, прикольная, но ввиду того, что публичные интерфейсные методы просачиваются в итоговый интерфейс класса, получается... ну, такое себе.
public static final HashMap<String, HashMap<Object, Object>> SYMBOLS = new HashMap<String, HashMap<Object, Object>>();
Т.е. работа в конкурентном окружении вообще не предполагается?
Интерфейс - понятие дизайна. Трейты - поняти имплементации. Универсалия - это специальный тип интерфейса, имеющий только одно свойство, указывающее на объект зависимости. интерфейсы с дефолтными методами - это способ их реализации. Про публичные методы я и написал в "ограничения". Это не моя проблема - это проблема Java, которая не дает нормально выполнить принцип дизайна ПО, о чем я так же написал. Но всем конечно, пофигу, на такое абстрактное понятие, как дизайн, потому что его никто не понимает, всем нравится писать уродский код.
Интерфейс - понятие дизайна. Трейты - поняти имплементации.
Т.е. с дизайном реализации можно не заморачиваться, я правильно понимаю вашу логику?
Но всем конечно, пофигу, на такое абстрактное понятие, как дизайн, потому что его никто не понимает, всем нравится писать уродский код.
Красота - понятие субъективное. Не, оно, конечно, круто добавить в реализацию интерфейс и сразу же получить требуемый функционал без каких-либо трудозатрат. Я тоже такое реализовывал, и оно даже работало. Но потом эта простота выходит боком, т.к. перестают думать надо/не надо: нужен функционал добавили интерфейс. А вот правильно ли вообще в данном месте реализовывать этот функционал?
Вообще миксины, конечно, круто, но они как @Transactional в спринге: не работает - добавим аннотацию, и оно само. В результате имеем кучу никому ненужного прокси-кода, который только на обогрев дата-центра работает.
Что значит с дизайном реализации можно не заморачиваться? Я заморочился и сделал самым простым возможным способом, чтобы доказать работоспособность метода. Ты говоришь, что все, что я написал -- это просто трейты, а я говорю что нет, что трейтами реализован принцип дизайна.
Красота -- это самое объективное понятие в мире. Чем больше развиваешься, тем больше видишь красивые вещи. Говорят что красота субъективна обычно те, кто ничего в этом не понимает.
Ну и что ты дальше написал? "А вот правильно ли вообще в данном месте реализовывать этот функционал?". Давай еще обсудим "а вот правильно ли вообще было идти программистом?" Почему такое отношение к профессионалам, как к полным дегенератам, которые не умеют думать? Что значит "правильно ли вообще реализовывать функционал" -- ну если мне нужна зависимость, то да, конечно правильно.
И я предлагаю вместо того, чтобы 40 классам делать одно и тоже свойство, выделить его и интерфейс, вернее даже специальную категорию интерфейсов, и имя им даже подобрал -- универсалии. Это вообще основной DRY. В чем ваша проблема всех? Зачем начинать упираться, приводить какие-то доводы доведенные до экстрима "перестают думать а нужен ли вообще функционал", минусовать комментарии автора, ничего конструктивного не приводя.
И к тому же, это не просто "добавить аннотацию". @Inject это просто добавить аннотацию. Тут же наоборот у тебя больше контроля к тому, что происходит, когда ты создаешь экземпляры через конструкторы, которым передаешь универсалии, ты уже знаешь, что используешь паттерн.
Такое чувство, что вместо гибкого DI опять пришли к Service Locator с глобальным состоянием.
Я лишь описал принцип, концепт дизайна. То, как его позволяет реализовать Джава - это проблема Джавы. Я не знаю, чем он вам недостаточно гибок, любые конкретные пожелания можно обсудить.
Вообще, одно другому не мешает. Просто getSymbols()
должен будет обращаться в DI-контекст за экземплярами. Это, кстати, поможет избежать таких неуродливых методов, типа init_XXX()
.
В книге Внедрение зависимостей на платформе .NET автор делает буквально то же самое: в начале книги реализует внедрение зависимостей через аргументы конструктора, а потом, понимая, что могут возникнуть циклические зависимости, предложил ввести для каждого метода отдельный класс - тот самый универсалий.
Только он пошел дальше, и дошел до медиатора
спасибо, что подсказал, посмотрю ) вау люди целые книги пишут по этому поводу...
Похоже, Вы не поняли книгу.
Там прямым текстом указывается, что способов внедрения зависимостей в наиболее общем случае 4 вида: в конструкторы, в методы, через свойства, через контекст. Предпочтительным является внедрение через конструктор, но он имеет ограничения в виде циклических зависимостей, которые решаются иными средствами, в зависимости от обстоятельств. В общем-то всё.
Нет, я ее понял.
Я сейчас не о том как правильно внедрять зависимости, а о том как книга написана:
Автор сначала приводит пример без зависимостей, потом добавляет внедрение через конструктор
Потом добавляет интерфейсы (на этом моменте он и рассказывает про эти 4 вида)
После выделяет каждый метод интерфейса в отдельный интерфейс
В конце говорит "а зачем нам куча интерфейсов, давайте медиатор запилим" - появляется медиатр, как цель всей нашей жизни
Принцип Универсалий: или локальный подход к Dependency Injection