Сообщение Re[3]: О пользе Dependency Injection от 13.01.2021 9:59
Изменено 13.01.2021 10:01 vsb
Re[3]: О пользе Dependency Injection
Здравствуйте, Министр Промышленности, Вы писали:
vsb>>Не очень понятно, чем ты предлагаешь их заменить. Я знаю несколько альтернатив: глобальные переменные; реестр объектов. Обе эти альтернативы мне не нравятся и имеют серьёзные минусы. В случае с DI минусов лично я не вижу. С тем, чтобы DI затруднял распутывание кода, я не сталкивался. Возможно ты сможешь пояснить, что именно ты имеешь в виду? Я, правда, пользуюсь Java.
МП>нормальные обычные конструкторы, ну либо статические конструкторы, если нужен пул объектов...
Я не понимаю тебя.
У меня есть один объект. Например назовём его UserDao. И есть второй объект. Назовём его AuthService. Для AuthService нужна ссылка на UserDao. Каким образом он эту ссылку получит?
Сконструировать он его не может. Во-первых я просто не хочу, чтобы в системе было много UserDao, например там может быть кеширование или ещё что угодно. Во-вторых для создания UserDao мне нужно соединение к БД, возможно ещё что-то. Передавать всю эту кучу скопом в AuthService (и в любой другой объект, которому нужен UserDao) это маразм.
Если я правильно понял про "статические конструкторы", ты предлагаешь сделать что-то вроде UserDao.getInstance(). То бишь реестр объектов, причём плохой и неудобный реестр. Так делать можно, но при этом возникает уйма проблем:
1. Такой код сложно тестировать. Если я хочу, чтобы AuthService принимал фейковый UserDao, мне нужно вызывать в тесте UserDao.setInstance(testUserDao). При этом мне в принципе нужно помнить при тестировании AuthService про все его зависимости. А ещё надо не забыть по окончании работы теста убрать все эти тестовые переменные, иначе это может поломать другие тесты. Ещё возникают вопросы с многопоточностью. В общем проблем много. Решать как-то их, наверное, можно, но неудобно.
2. Такой код сложно переиспользовать. Если мне всё же понадобится в реальном коде другой UserDao конкретно для AuthService, то это будет просто невозможно сделать в рамках данного подхода.
3. Непонятно, собственно, к чему мы пришли в итоге. У нас есть вызов UserDao.getInstance(), который возвращает что-то. Что он возвращает? Неизвестно. Кто-то там ему сделал setInstance раньше, его и возвращает. Какая разница с DI в плане понимания работы кода? Никакой разницы.
vsb>>Не очень понятно, чем ты предлагаешь их заменить. Я знаю несколько альтернатив: глобальные переменные; реестр объектов. Обе эти альтернативы мне не нравятся и имеют серьёзные минусы. В случае с DI минусов лично я не вижу. С тем, чтобы DI затруднял распутывание кода, я не сталкивался. Возможно ты сможешь пояснить, что именно ты имеешь в виду? Я, правда, пользуюсь Java.
МП>нормальные обычные конструкторы, ну либо статические конструкторы, если нужен пул объектов...
Я не понимаю тебя.
У меня есть один объект. Например назовём его UserDao. И есть второй объект. Назовём его AuthService. Для AuthService нужна ссылка на UserDao. Каким образом он эту ссылку получит?
Сконструировать он его не может. Во-первых я просто не хочу, чтобы в системе было много UserDao, например там может быть кеширование или ещё что угодно. Во-вторых для создания UserDao мне нужно соединение к БД, возможно ещё что-то. Передавать всю эту кучу скопом в AuthService (и в любой другой объект, которому нужен UserDao) это маразм.
Если я правильно понял про "статические конструкторы", ты предлагаешь сделать что-то вроде UserDao.getInstance(). То бишь реестр объектов, причём плохой и неудобный реестр. Так делать можно, но при этом возникает уйма проблем:
1. Такой код сложно тестировать. Если я хочу, чтобы AuthService принимал фейковый UserDao, мне нужно вызывать в тесте UserDao.setInstance(testUserDao). При этом мне в принципе нужно помнить при тестировании AuthService про все его зависимости. А ещё надо не забыть по окончании работы теста убрать все эти тестовые переменные, иначе это может поломать другие тесты. Ещё возникают вопросы с многопоточностью. В общем проблем много. Решать как-то их, наверное, можно, но неудобно.
2. Такой код сложно переиспользовать. Если мне всё же понадобится в реальном коде другой UserDao конкретно для AuthService, то это будет просто невозможно сделать в рамках данного подхода.
3. Непонятно, собственно, к чему мы пришли в итоге. У нас есть вызов UserDao.getInstance(), который возвращает что-то. Что он возвращает? Неизвестно. Кто-то там ему сделал setInstance раньше, его и возвращает. Какая разница с DI в плане понимания работы кода? Никакой разницы.
Re[3]: О пользе Dependency Injection
Здравствуйте, Министр Промышленности, Вы писали:
vsb>>Не очень понятно, чем ты предлагаешь их заменить. Я знаю несколько альтернатив: глобальные переменные; реестр объектов. Обе эти альтернативы мне не нравятся и имеют серьёзные минусы. В случае с DI минусов лично я не вижу. С тем, чтобы DI затруднял распутывание кода, я не сталкивался. Возможно ты сможешь пояснить, что именно ты имеешь в виду? Я, правда, пользуюсь Java.
МП>нормальные обычные конструкторы, ну либо статические конструкторы, если нужен пул объектов...
Я не понимаю тебя.
У меня есть один объект. Например назовём его UserDao. И есть второй объект. Назовём его AuthService. Для AuthService нужна ссылка на UserDao. Каким образом он эту ссылку получит?
Сконструировать он его не может. Во-первых я просто не хочу, чтобы в системе было много UserDao, например там может быть кеширование или ещё что угодно. Во-вторых для создания UserDao мне нужно соединение к БД, возможно ещё что-то. Передавать всю эту кучу скопом в AuthService (и в любой другой объект, которому нужен UserDao) это маразм.
Если я правильно понял про "статические конструкторы", ты предлагаешь сделать что-то вроде UserDao.getInstance(). То бишь реестр объектов, причём плохой и неудобный реестр. Так делать можно, но при этом возникает уйма проблем:
1. Такой код сложно тестировать. Если я хочу, чтобы AuthService принимал фейковый UserDao, мне нужно вызывать в тесте UserDao.setInstance(testUserDao). При этом мне в принципе нужно помнить при тестировании AuthService про все его зависимости. А ещё надо не забыть по окончании работы теста убрать все эти тестовые переменные, иначе это может поломать другие тесты. Ещё возникают вопросы с многопоточностью. В общем проблем много. Решать как-то их, наверное, можно, но неудобно.
2. Такой код сложно переиспользовать. Если мне всё же понадобится в реальном коде другой UserDao конкретно для AuthService, то это будет просто невозможно сделать в рамках данного подхода.
3. Непонятно, собственно, к чему мы пришли в итоге. У нас есть вызов UserDao.getInstance(), который возвращает что-то. Что он возвращает? Неизвестно. Кто-то там ему сделал setInstance раньше, его и возвращает. Какая разница с DI в плане понимания работы кода? Никакой разницы.
4. Сложно понять, от чего зависит AuthService. Нужно внимательно читать его код, изучать список импортов. В случае с DI ты просто смотришь на параметры конструктора и всё как на ладони. Это бывает удобно.
vsb>>Не очень понятно, чем ты предлагаешь их заменить. Я знаю несколько альтернатив: глобальные переменные; реестр объектов. Обе эти альтернативы мне не нравятся и имеют серьёзные минусы. В случае с DI минусов лично я не вижу. С тем, чтобы DI затруднял распутывание кода, я не сталкивался. Возможно ты сможешь пояснить, что именно ты имеешь в виду? Я, правда, пользуюсь Java.
МП>нормальные обычные конструкторы, ну либо статические конструкторы, если нужен пул объектов...
Я не понимаю тебя.
У меня есть один объект. Например назовём его UserDao. И есть второй объект. Назовём его AuthService. Для AuthService нужна ссылка на UserDao. Каким образом он эту ссылку получит?
Сконструировать он его не может. Во-первых я просто не хочу, чтобы в системе было много UserDao, например там может быть кеширование или ещё что угодно. Во-вторых для создания UserDao мне нужно соединение к БД, возможно ещё что-то. Передавать всю эту кучу скопом в AuthService (и в любой другой объект, которому нужен UserDao) это маразм.
Если я правильно понял про "статические конструкторы", ты предлагаешь сделать что-то вроде UserDao.getInstance(). То бишь реестр объектов, причём плохой и неудобный реестр. Так делать можно, но при этом возникает уйма проблем:
1. Такой код сложно тестировать. Если я хочу, чтобы AuthService принимал фейковый UserDao, мне нужно вызывать в тесте UserDao.setInstance(testUserDao). При этом мне в принципе нужно помнить при тестировании AuthService про все его зависимости. А ещё надо не забыть по окончании работы теста убрать все эти тестовые переменные, иначе это может поломать другие тесты. Ещё возникают вопросы с многопоточностью. В общем проблем много. Решать как-то их, наверное, можно, но неудобно.
2. Такой код сложно переиспользовать. Если мне всё же понадобится в реальном коде другой UserDao конкретно для AuthService, то это будет просто невозможно сделать в рамках данного подхода.
3. Непонятно, собственно, к чему мы пришли в итоге. У нас есть вызов UserDao.getInstance(), который возвращает что-то. Что он возвращает? Неизвестно. Кто-то там ему сделал setInstance раньше, его и возвращает. Какая разница с DI в плане понимания работы кода? Никакой разницы.
4. Сложно понять, от чего зависит AuthService. Нужно внимательно читать его код, изучать список импортов. В случае с DI ты просто смотришь на параметры конструктора и всё как на ладони. Это бывает удобно.