Внедряете ли вы зависимости в конструктор, даже если класс не владеет этими зависимостями, а использует их в методах?

Если класс School зависит от класса EmailSender, вам, возможно, придется внедрить этот EmailSender через его конструктор с универсальным интерфейсом, таким как IMessagable, IMessageSender или даже IEmailSender, чтобы в будущем его можно было заменить чем-то другим.

Для этого вы должны создать закрытое поле только для чтения в классе School.

Но тогда вы говорите, что School HAS-A MessageSender, но, конечно же, он просто ИСПОЛЬЗУЕТ его в нескольких своих методах ??

а в чем вопрос?

MakePeaceGreatAgain 13.12.2020 16:26

как определить зависимость. Это то, что класс имеет или использует? Или и то, и другое, и, следовательно, как вы различаете, чем владеет класс, и тем, что он использует?

BeingCraigSchwartz 13.12.2020 16:28

с точки зрения класса нет никакой разницы между отношением «имеет» и отношением «использует». На самом деле вы наверняка можете использовать то, что у вас есть, не так ли? Так что совершенно нормально использовать зависимости, предоставляемые полем.

MakePeaceGreatAgain 13.12.2020 16:31

это не то же самое, что школа, имеющая зависимость от IStudentCollection, не так ли? В этих отношениях есть более четкая связь. Конечно, EmailSender следует передавать только в методы, в которых он используется, а не быть атрибутом класса? Я надеюсь, что вы можете развеять мою путаницу. Спасибо!

BeingCraigSchwartz 13.12.2020 16:33

У класса должно быть что-то, чтобы его использовать. Даже если это интерфейс, он все равно сводится к необходимости конкретного типа, который выполняет контракт, определенный IStudentCollection.

ProgrammingLlama 13.12.2020 16:35

в «Школе» есть «студенты: IStudentCollection», но в школе нет «emailSender: EmailSender». Имеет больше смысла передавать его только в методы, в которых он используется; вот почему инъекция зависимостей сбивает меня с толку.

BeingCraigSchwartz 13.12.2020 16:38

Школа - нет, но тогда школа звучит как модель, а не служба. SchoolControllerService будет иметь и использовать emailSender на основе данных в SchoolModel.

ProgrammingLlama 13.12.2020 16:38

Для меня это больше похоже на проблему моделирования, чем на проблему DI. Игнорируя какие-либо/все концепции DI, вы думаете, что School отвечает за отправку электронных писем? Кажется, вы согласны с тем, что ответ отрицательный. Вероятно, будет введена какая-то другая абстракция, которая будет более ответственной за отправку электронных писем/уведомлений в этих случаях (например, отдел зачисления). При правильных абстракциях зависимости должны быть ясны.

devNull 13.12.2020 16:54

зачем тебе иметь отношения, если ты не сможешь их использовать никоим образом? Весь смысл зависимости в том, чтобы что-то с ней делать — это использовать ее. Если вы им не пользуетесь, в первую очередь нет причин его иметь.

MakePeaceGreatAgain 13.12.2020 18:22

У Shool есть Sender, чтобы его использовать, не так ли?

MakePeaceGreatAgain 13.12.2020 18:25

но отправитель не принадлежит к школе не так ли?

BeingCraigSchwartz 13.12.2020 18:28

ну, человек, наверное, работает в школе, так что в каком-то смысле школа есть, если хотите.

MakePeaceGreatAgain 13.12.2020 18:36

но мы говорим об отправителе электронной почты. Это может быть регистратор, который ведет журнал. Это может быть что угодно, что School или SchoolService использует, но не владеет.

BeingCraigSchwartz 13.12.2020 18:40
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
13
338
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Даже если класс использует только один из многих методов переданного объекта, весь объект по-прежнему считается зависимостью класса.

Это становится очевидным, когда вы меняете API (сигнатуры методов) объекта. Передавая этот объект классу, вы, по сути, гарантируете «контракт» этого объекта. Если вы измените API этого объекта, вы рискуете сломать классы, которые от него зависят.

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

Номенклатура IS-A и HAS-A используется в основном для того, чтобы отличить наследование от состава.

Любое свойство/член, объявленное классом, является чем-то, что есть у класса.

Has-A здесь для того, чтобы отличаться от Is-A наследственности.

Свойство «использует» больше связано с классовой сплоченностью, чем с составом. Если у класса есть свойство-A, но он его не использует или использует в небольшом проценте функций, у него низкая связность.

И HAS-A, и IS-A являются зависимостями класса. Вот почему мы стремимся, чтобы они оба были абстракциями, чтобы слабо связать их.

Любое определение класса/интерфейса, без которого ваш класс не будет компилироваться, является зависимостью. Даже если он не имеет отношения HAS-A и просто передается как параметр функции.

Другие вопросы по теме