Правила     Закладки     Карма    Календарь    Журналы    Помощь    Поиск    PDA    Чат   
        СМС-ки
   
Пейджер выключен!
 
Фильтр авторов:    показать 
  скрыть
  Ответ в темуСоздание новой темыСоздание опроса

> Принципы SOLID, принцип Open-closed
clocwerk  
 ۩  [x] Дата
Цитировать сообщение

Пользователя сейчас нет на форуме



Новичок
*

Профиль
Группа: Пользователь
Сообщений: 36
Пользователь №: 41868
На форуме: 1 год, 2 месяца, 10 дней
Карма: 1




Добрый день всем. Сейчас читаю статью про принципы SOLID, и пытаюсь разобраться, но вот что то не могу понять, вот пример, который приводит автор статьи:

class OrderRepository
{
private $source;

public function setSource(IOrderSource $source)
{
$this->source = $source;
}

public function load($orderID)
{
return $this->source->load($orderID);
}
public function save($order){/*...*/}
public function update($order){/*...*/}
}


interface IOrderSource
{
public function load($orderID);
public function save($order);
public function update($order);
public function delete($order);
}

class MySQLOrderSource implements IOrderSource
{
public function load($orderID);
public function save($order){/*...*/}
public function update($order){/*...*/}
public function delete($order){/*...*/}
}


class ApiOrderSource implements IOrderSource
{
public function load($orderID);
public function save($order){/*...*/}
public function update($order){/*...*/}
public function delete($order){/*...*/}
}


И после этого пишет коментарий:
Цитата
Таким образом, мы можем изменить источник и соответственно поведение для класса OrderRepository, установив нужный нам класс реализующий IOrderSource, без изменения класса OrderRepository.

Но... классы ApiOrderSource и MySQLOrderSource вобще никак не связаны с классом OrderRepository, не наследуются от него, ни клонируют и вобще не знают о его существовании, как тогда мы можем изменить поведение класса OrderRepository? Да и интерфейс IOrderSource тоже никак не связан с этим классом, ну кроме что метода setSource. Подскажите, пожалуйста, в чем я ошибаюсь?
PM
    0   Для быстрого поиска похожих сообщений выделите 1-2 слова в тексте и нажмите сюда Для быстрой цитаты из этого сообщения выделите текст и нажмите сюда
Invis1ble  
Дата
Цитировать сообщение

Пользователя сейчас нет на форуме




******

Профиль
Группа: Эксперт
Группа переписки
Сообщений: 11783
Пользователь №: 23195
На форуме: 6 лет, 4 месяца, 10 дней
Карма: 429

Трезвый :
7 лет, 3 месяца, 10 дней


Цитата (clocwerk @ 29.08.2016 - 17:26)
Но... классы ApiOrderSource и MySQLOrderSource вобще никак не связаны с классом OrderRepository, не наследуются от него, ни клонируют и вобще не знают о его существовании, как тогда мы можем изменить поведение класса OrderRepository?

Внедрив другой source с помощью OrderRepository::setSource().


--------------------
PMПисьмо на e-mail пользователюСайт пользователя
    0   Для быстрого поиска похожих сообщений выделите 1-2 слова в тексте и нажмите сюда Для быстрой цитаты из этого сообщения выделите текст и нажмите сюда
Another Reality  
Дата
Цитировать сообщение

Пользователя сейчас нет на форуме



Старик
***

Профиль
Группа: Пользователь
Сообщений: 124
Пользователь №: 41606
На форуме: 1 год, 4 месяца, 17 дней
Карма: 5




Принцип открытости/закрытости устанавливает такое правило: классы должны быть открыты для расширения, но закрыты для изменения.

Например:
Мы имеем некую модель, задача которой - совершать операции с базой данных.
Предположим, что модель универсальная и может использоваться в различных местах и проектах.
Но есть проблема - мы понятия не имеем с какой базой и через какой драйвер работают эти пректы.
1-й вариант решения проблемы: каждый раз переписывать внутренность модели, подстраивая ее под проекты.
2-й вариант - сделать один интерфейс для всех вариантов баз данных и по интерфейсной ссылке (в примере у класса OrderRepository в методе setSource(IOrderSource $source)) передавать туда нужный нам объект через который будет осуществляться работа с БД.
В итоге нашей модели глубоко плевать на то, с какой базой идет работа и мы не вносим изменений в нашу модель.
Именно это показано в примере.

Кстати, сразу же реализовывается принцип инверсии зависимостей.

Это сообщение отредактировал Another Reality - 29.08.2016 - 21:49
PMПисьмо на e-mail пользователю
    1   Для быстрого поиска похожих сообщений выделите 1-2 слова в тексте и нажмите сюда Для быстрой цитаты из этого сообщения выделите текст и нажмите сюда
clocwerk  
 ۩  Дата
Цитировать сообщение

Пользователя сейчас нет на форуме



Новичок
*

Профиль
Группа: Пользователь
Сообщений: 36
Пользователь №: 41868
На форуме: 1 год, 2 месяца, 10 дней
Карма: 1




Another Reality
Спасибо за развернутый ответ, посдкажите пожалуйста еще, получается вот эта часть кода
class OrderRepository
{
private $source;

public function setSource(IOrderSource $source)
{
$this->source = $source;
}

public function load($orderID)
{
return $this->source->load($orderID);
}
public function save($order){/*...*/}
public function update($order){/*...*/}
}

и есть внедрение зависимостей? Т.е. далее можно будет это использовать вот так:

$someVariable = new OrderRepository;
$someVariable->setSource(new ApiOrderSource);
$someVariable->load();

Правильно я понимаю?

Invis1ble
Вы пишите
Цитата
Внедрив другой source с помощью OrderRepository::setSource().
но setSource же не статический метод его можно так вызвать? Это какой то частный случай?
PM
    0   Для быстрого поиска похожих сообщений выделите 1-2 слова в тексте и нажмите сюда Для быстрой цитаты из этого сообщения выделите текст и нажмите сюда
Another Reality  
[x] Дата
Цитировать сообщение

Пользователя сейчас нет на форуме



Старик
***

Профиль
Группа: Пользователь
Сообщений: 124
Пользователь №: 41606
На форуме: 1 год, 4 месяца, 17 дней
Карма: 5




Цитата (clocwerk @ 30.08.2016 - 09:16)
Another Reality
Спасибо за развернутый ответ, посдкажите пожалуйста еще, получается вот эта часть кода
class OrderRepository
{
private $source;

public function setSource(IOrderSource $source)
{
$this->source = $source;
}

public function load($orderID)
{
return $this->source->load($orderID);
}
public function save($order){/*...*/}
public function update($order){/*...*/}
}

и есть внедрение зависимостей? Т.е. далее можно будет это использовать вот так:

$someVariable = new OrderRepository;
$someVariable->setSource(new ApiOrderSource);
$someVariable->load();

Правильно я понимаю?

Совершенно верно.
Для пущей ясности сдлаем так:


class MySQL implements IOrderSource
{
public function load($orderID);
public function save($order){/*...*/}
...
}

class PostgreSQL implements IOrderSource
{
public function load($orderID);
public function save($order){/*...*/}
...
}

class MSSQLServer implements IOrderSource
{
public function load($orderID);
public function save($order){/*...*/}
...
}

$someVariable = new OrderRepository;
$someBase = new MySQL // или PostgreSQL или MSSQLServer
$someVariable->setSource($someBase);
$someVariable->load();


В итоге объект класса OrderRepository работает с любой базой.
PMПисьмо на e-mail пользователю
    0   Для быстрого поиска похожих сообщений выделите 1-2 слова в тексте и нажмите сюда Для быстрой цитаты из этого сообщения выделите текст и нажмите сюда
clocwerk  
 ۩  Дата
Цитировать сообщение

Пользователя сейчас нет на форуме



Новичок
*

Профиль
Группа: Пользователь
Сообщений: 36
Пользователь №: 41868
На форуме: 1 год, 2 месяца, 10 дней
Карма: 1




Another Reality
Спасибо огромное! Прям глаза мне открыли теперь попробую написать несколько своих классов используя DI
PM
    0   Для быстрого поиска похожих сообщений выделите 1-2 слова в тексте и нажмите сюда Для быстрой цитаты из этого сообщения выделите текст и нажмите сюда
Another Reality  
Дата
Цитировать сообщение

Пользователя сейчас нет на форуме



Старик
***

Профиль
Группа: Пользователь
Сообщений: 124
Пользователь №: 41606
На форуме: 1 год, 4 месяца, 17 дней
Карма: 5




Та пожалуйста.
Удачи!
PMПисьмо на e-mail пользователю
    0   Для быстрого поиска похожих сообщений выделите 1-2 слова в тексте и нажмите сюда Для быстрой цитаты из этого сообщения выделите текст и нажмите сюда
Гость_Invis1ble  
Дата
Цитировать сообщение


Гость пожелал остаться неизвестным

Unregistered









Цитата (clocwerk @ 30.08.2016 - 09:16)
setSource же не статический метод его можно так вызвать? Это какой то частный случай?

Это не вызов, а просто общепринятый способ записи метода, чтобы показать, что метод принадлежит такому-то классу.
    0   Для быстрого поиска похожих сообщений выделите 1-2 слова в тексте и нажмите сюда Для быстрой цитаты из этого сообщения выделите текст и нажмите сюда
  Быстрый ответ
Информация о Госте
Введите Ваше имя
Кнопки кодов
Для вставки цитаты, выделите нужный текст и
НАЖМИТЕ СЮДА
Введите сообщение
Смайлики
:huh:  :o  ;) 
:P  :D  :lol: 
B)  :rolleyes:  <_< 
:)  :angry:  :( 
:unsure:  :blink:  :ph34r: 
     
Показать всё

Опции сообщения  Включить смайлики?
 Включить подпись?
 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:

Опции темы Ответ в темуСоздание новой темыСоздание опроса