Форум программистов, компьютерный форум, киберфорум
PHP: ООП
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.67/6: Рейтинг темы: голосов - 6, средняя оценка - 4.67
0 / 0 / 0
Регистрация: 27.04.2019
Сообщений: 22
1

Принцип DIP из SOLID

08.02.2020, 23:57. Просмотров 1098. Ответов 4

Правильно ли я понял принцип DIP из SOLID?
Если класс A имеет зависимость от класса B, то при описании класса А зависимость нужно указать через абстракцию, т.е.:

Код
interface BInterface { ... }

class B implements BInterface  { ... }

class A {
    public function __construct(BInterface  $b) { ... }
}
Если бы мы указали в зависимости, конкретно класс, вот так:

Код
class A {
    public function __construct(B $b) { ... }
}
то это было бы нарушение принципа DIP ?
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
08.02.2020, 23:57
Ответы с готовыми решениями:

Пятый принцип SOLID
Здравствуйте. Формулировка пятого принципа гласит о том, что модули верхнего уровня не должны...

CPLD в DIP
Я и не знал, а оказывается Atmel тянется к радиолюбителям:)...

Цанговые DIP-панельки
Запаял тут пару цанговых DIP40 в пинборд и крепко так призадумался - а не поменять ли их на...

Демонтаж микрухи в DIP-40
Есть какие-то идеи как сие осуществить??? Пробовал феном греть.... грел минут 10.. не помогло.....

4
Почетный модератор
Эксперт HTML/CSSЭксперт PHP
16817 / 6695 / 880
Регистрация: 12.06.2012
Сообщений: 19,968
09.02.2020, 15:03 2
Да, верно. Т.к. в таком случае класс А не завязан на конкретную реализацию и можно подменить в дальнейшем реализацию на любую другую, реализующую общий интерфейс.
1
0 / 0 / 0
Регистрация: 27.04.2019
Сообщений: 22
09.02.2020, 16:06  [ТС] 3
Спасибо большое!

Получается, что всегда зависимости нужно указывать от интерфейсов или абстрактных классов ? Бывают ли исключения, и когда ?

Добавлено через 9 минут
Так же, самое главный вопрос (ради которого задал текущий), такой:

Если, по принципу DIP (или не обязательно принципу, в целом, при проектировании малосвязных компонентов), зависимость должна быть на абстракциях (насколько правильно я понял, это abstract class или interface).

В этом случае, при использовании DI-контейнеров с автовариангом (Autowiring), работать не будет - и это логично. (пруф на всякий случай).

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

Тогда в чем смысл автовайринга, если всеравно нужно вручную устанавливать зависимости в контейнере ?

Или я что-то не правильно интерпретировал ? Просьба подробно разъяснить.
0
Почетный модератор
Эксперт HTML/CSSЭксперт PHP
16817 / 6695 / 880
Регистрация: 12.06.2012
Сообщений: 19,968
09.02.2020, 17:16 4
Лучший ответ Сообщение было отмечено SystemException как решение

Решение

Цитата Сообщение от SystemException Посмотреть сообщение
Бывают ли исключения, и когда ?
когда архитектура грозит перерасти в антипаттерн Anti-DIP Если вы для каждого класса будете делать интерфейс только для того, чтобы он был - в конечном итоге это может привести к неоправданно большому разрастанию.. В примере ниже класс Message не является интерфейсом (хотя подобное использование тоже под вопросом, но лично я считаю, что здесь может быть неоправданно реализовать интерфейс)
Цитата Сообщение от SystemException Посмотреть сообщение
Тогда в чем смысл автовайринга, если всеравно нужно вручную устанавливать зависимости в контейнере ?
как раз в этом и смысл. Вы в любой момент можете подменить реализацию, которая будет инстанционирована для данного контекста, причем даже во время выполнения программы. По ссылке речь идет о "необъектных" аргументов, для таких моментов вы можете указать создаваемый объект другим способом, явно. Но это все равно будет лучше, нежели вы не будете использовать IoC.
Например, представьте ситуацию, что.. Ну, пусть будет отправка уведомления пользователю. У вас есть код такого вида:
PHP
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
class Message
{
    //....
}
interface NotifierInterface
{
    public function notify(Message $message);
}
class EmailNotifier implements NotifierInterface
{
    public function __construct()
    {
        
    }
 
    public function notify(Message $message)
    {
        //send email..
    }
}
class SMSNotifier implements NotifierInterface
{
    private $smsProvider;
    public function __construct(SMSProviderInterface $smsProvider)
    {
        $this->smsProvider = $smsProvider;
    }
    public function notify(Message $message)
    {
        //send sms via smsProvider..
    }
}
 
class MessageObserver
{
    private $notifier;
    public function __construct(NotifierInterface $notifier)
    {
        $this->notifier = $notifier;
    }
 
    public function onNewMessage(Message $message)
    {
        $this->notifier->notify($message);
    }
}
 
//.... допустим, где-то появилось какое-то новое сообщение:
$messageObserver->onNewMessage($message);
Так вот, в данном случае, если бы MessageObserver был завязан на конкретную реализацию (например, EmailNotifier), то при необходимости поменять на смс, вам бы пришлось лезть в этот код с изменениями, заменяя тип класса.. А конструкторы у этих классов разные, как можно заметить. Вот здесь вам и пригодится автовайринг.
Как видно, в классе SMSNotifier также есть зависимость от SMSProviderInterface, с какой-то реализацией, которая также может требовать еще какие-то данные, и вручную все это указывать - может вызвать слишком много работы. При использовании автовайринга вы перекладываете весь этот процесс создания объектов по цепочке выше на контейнер, а не вручную все инициализируете. В контейнере при этом у вас будет всего нечто наподобие такого:
PHP
1
2
3
4
return [
    NotifierInterface::class => DI\create(SMSNotifier::class),
    SMSProviderInterface::class => DI\create(SMSRuProvider::class), //используем провайдер sms.ru
];
Класс SMSRuProvider может также требовать какие-то данные для создания, которые могут также быть описаны в контейнере - вы избавляете себя от необходимости прописывать все-все создаваемые так сказать "зависимые" объекты.
Причем, при необходимости, вы можете забиндить свои алиасы для разных стратегий отправки

Добавлено через 6 минут
смысл не в том, что не надо указывать зависимости. Смысл в том, что вы указываете их не для каждого получения объекта, а только один раз описываете, а потом используете. Понадобилось использовать вместо SMS e-mail - поменяли в контейнере создаваемый класс и все, не надо бегать по всем местам использования и менять. Понадобилось изменить аргументы в конструкторе и т.п., вы это описали один раз, а не меняете в каждом месте, где вы работали с этим объектом
2
0 / 0 / 0
Регистрация: 27.04.2019
Сообщений: 22
09.02.2020, 20:02  [ТС] 5
спасибо большое за развернутый ответ! все понял!
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
09.02.2020, 20:02

Заказываю контрольные, курсовые, дипломные и любые другие студенческие работы здесь.

Cобытийность. Принцип использования и принцип работы событий в jQ и GCT
Добрый день. Подготавливаюсь к собеседованию по чеклисту и не могу найти ответ на вопрос:...

DIP-switch. Как подключить?
Здравствуйте! Нужна помощь. Вот само задание: Управление вентиляцией помещения на основе...

Пунктирная линия dip trace.
Всех приветствую. Можно ли в DT в схематике нарисовать пунктирный прямоугольник, для того чтобы...

64 уровня на вх АЦП 6 ch DIP переключателем
Возможно ли с помощью одного или двумя входами АЦП сделать опрос 6-ти канального DIP выключателя...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
5
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2020, vBulletin Solutions, Inc.