Эпизод 4. О – OCP: The Open Closed Principle

Приветствую вас в 4-ом эпизоде сериала “ООП здорового человека”. Здесь речь пойдет о 2-ом принципе SOLID – открытость-закрытость кода…

Теория

Принцип открытости-закрытости. Книга: Вы должны иметь возможность расширять поведение классов, не изменяя его. Вероятно, сложно и непонятно, по крайней мере – это мои ощущения при первой встрече с этой формулировкой. Но немного подумав, я понял, что это объясняется так: класс может быть расширен новыми методами, но при этом дочерний класс никоем образом не переопределяет классы родителя.

Здесь я немного припух: как так – дядя Боб(на деле – первая формулировка сиего принципа принадлежит Бертрану Мейеру) запрещает использовать одну из возможностей ООП? Ну-да… полазив в интернете, посмотрев иные трактовки(а также пример в книге Роба) – нет! Речь идет не о наследовании, а о порождении объекта класса для дальнейшего использования(что, в принципе, не перечит моей трактовке… однако, я не представляю – как не переопределять методы родителя в некоторых ситуациях…).

Речь, как я понял(если откинуть мою трактовку) об объектном полиморфизме. Смысл в том, чтоб при создании метода (вызывающего класс в процессе работы) была предусмотрена возможность изменить вызываемый класс, не изменяя, при этом, сам метод. Кста, мы уже знаем о SRP, поэтому в его контексте: при соблюдении OCP также будет соблюден SRP, поскольку точка зависимости от чужого класса останется одной.

Примеры

№1: печатная машинка и компьютер с принтером; и там и там пользуясь клавиатурой происходит набор текста, затем краска на бумаге отображает набранное. Интерфейс одинаков, результат тоже – различные только механизмы между точками.

Практика

Для иллюстрации этого принципа рассмотрим класс Product(из этой статьи); а именно – метод получения данных о продукте. Дело в том ,что эти данные где-то лежат; соответственно, нужно установить связь с хранилищем, составить запрос и исполнить его – и всем этим занимается отдельный(-е) класс. Представим это так

<?php
class Product
{
    // достать инфо  о продукте:
    // -- дергаем Storage и строим запрос
    // -- приказываем выполнить его
    // дергаем Currency и пересчитываем цену продукта
}

class Storage
{
    // Устанавливаем соединение с хранилищем
    // выполняем запрос
}

Теперь, хранилища могут быть разные(MySQL, MongoDB, обычный файл…); у каждого свой способ соединения и свой способ задать вопрос – в общем свой класс. Этот принцип о том, что класс Storage должен проектироваться так, чтоб он мог работать с классом любой БД:

<?php
class Storage
{
    // Приказ об устанавлении соединения с хранилищем:
    // -- получим инфу об используемой БД
    // -- инициализируем новый экземпляр для работы с БД
    // выполняем запрос
}

ну и, как все понимают, классы работы с хранилищами должны иметь одинаковые методы. Для реализации данного принципа построения кода придуманы дизайн-паттерны кода – Стратегия и  Шаблонный метод; разберу эти паттерны позже – в этой же статейке я хотел показать, что в подобных ситуациях(когда логика говорит о возможности появлении вариантов развития системы) – используй порождение объекта, а не наследование его класса. Можно конечно и начальный способ оставить – но это чревато ошибками в будущем… и это уже не про мой сериал.

Добавить комментарий

Ваш адрес email не будет опубликован.

*

code