TL; DR - Нет очевидной связи, которую нужно исправить. Зависимость от абстракций велика, но можно увлекаться и добавлять их там, где они нам не нужны. Создавайте абстракции с точки зрения других классов, которые будут зависеть от них , когда вы знаете, что они вам нужны , так что вы всегда пишете нужный код, а не код, который вам не нужен.
Для вашего класса создание экземпляров A
не плохая связь. Создание экземпляров A
является очевидной целью B
. B
не зависит от A
в том смысле, что он никоим образом не использует его. Он просто создает A
и возвращает его, потому что это то, что он должен делать.
Другой способ взглянуть на это - как метод, который возвращает A
, не может быть каким-либо образом связан с A
? B
не нужен завод. Это это фабрика.
Нет также очевидной причины, по которой вам нужна абстракция для представления A
. Если вам нужно было смоделировать A
, вы можете определить интерфейс как IA
. Но ничто, показанное здесь, не означает, что вам это нужно. Создать «настоящий» экземпляр A
так просто, что нет необходимости его высмеивать.
var a = new A("February");
. Что издеваться?
И если вам нужна абстракция для A
(например, IA
), то единственное изменение, которое необходимо немедленно сделать в B
, это изменить SomeMethod
, чтобы вернуть List<IA>
вместо List<A>
. В рамках этого метода вы создадите List<IA>
вместо List<A>
, но вы все равно будете заполнять его конкретными экземплярами A
.
Связывание, которое будет удалено (которое, как я подчеркнул, не показано в вашем коде), будет с другими классами, которые не показаны, которые в настоящее время зависят от A
и зависят от B
для обеспечения Это. Теперь они будут зависеть от B
для предоставления IA
, поэтому эти другие классы больше не будут связаны с A
.
Абстракция великолепна, но она может стать кроличьей ношей, где мы начнем добавлять интерфейсы и фабрики, которые нам на самом деле не нужны. (Что происходит, когда вы закончите замену A
на IA
? Теперь вы подключены к List<T>
- что с этим делать?) Если вы не можете протестировать один класс без проверки его зависимостей, это хороший признак того, что зависимость должна быть абстракцией, над которой можно издеваться.
Если вы можете протестировать все - что в этом случае вы можете - тогда введение большего количества абстракции - это просто создание работы, которая вам не нужна. Это не значит, что я бы никогда не начал с абстракций. Во многих случаях совершенно очевидно, что мне это понадобится. Обычно это происходит в тех случаях, когда я собираюсь что-то сделать с зависимостью. В этом случае вы просто возвращаете его.
Вот другой способ взглянуть на это: если вам нужна абстракция, скорее всего, это будет абстракция к , представляющему B
. Если другие классы, не показанные здесь, нуждаются в экземплярах A
или IA
, и логика их создания была бы немного более сложной, то эти классы могли бы зависеть от фабрики, например
interface ISomethingFactory
{
List<IA> Create();
}
B
будет реализацией этой фабрики.
Мы должны определить абстракции с точки зрения классов, которые от них зависят. Как они будут взаимодействовать с этой зависимостью? Нужно ли мне издеваться над этой зависимостью, и если да, то как я это сделаю? Когда мы смотрим на классы как на зависимости (или нуждающиеся ) зависимости, тогда мы пишем код, основанный на реальных потребностях. Это может помешать нам спуститься по кроличьей норе и написать код, который нам не нужен (что я делал бесчисленное количество раз.)