Принципы SOLID в ООП или легкий способ бросить курить. Часть 1 из 5.

5 мин. на чтение

Осторожно, вольное (опытное) трактование канонов программирования! Автор написал эту статью после безуспешных попыток научить молодых программистов «по книжкам», которое потерпело жесткое фиаско ввиду неочевидности и запутанности объяснения принципов SOLID.

Кажется нет более легкого способа бросить курить чем детально изучить принципы объектно-ориентированного программирования SOLID на примере скажем двух языков – PHP и JavaScript 😂 Перефразировав классика квантовой механики, можно с уверенностью сказать: если вы изучили SOLID и вам не стало страшно, вы не поняли SOLID.

По современным меркам (в сравнении с языком C, который появился в 1972 году) принципы хоть и не молоды, но их впервые собрал воедино в 2000-м году Роберт Мартин в авторской статье Design Principles and Design Patterns.

SOLID это [itg-tooltip href=»http://tooltip» tooltip-content=»<p><strong style=&aquot;color: #222222; font-family: sans-serif;&aquot;>Мнемо́ника</strong><span style=&aquot;color: #222222; font-family: sans-serif;&aquot;> (</span><a style=&aquot;text-decoration-line: none; color: #0b0080; background-image: none; background-position: initial; background-size: initial; background-repeat: initial; background-attachment: initial; background-origin: initial; background-clip: initial; font-family: sans-serif;&aquot; title=&aquot;Древнегреческий язык&aquot; href=&aquot;https://ru.wikipedia.org/wiki/%D0%94%D1%80%D0%B5%D0%B2%D0%BD%D0%B5%D0%B3%D1%80%D0%B5%D1%87%D0%B5%D1%81%D0%BA%D0%B8%D0%B9_%D1%8F%D0%B7%D1%8B%D0%BA&aquot;>др.-греч.</a><span style=&aquot;color: #222222; font-family: sans-serif;&aquot;> </span><span lang=&aquot;grc&aquot; style=&aquot;color: #222222; font-family: sans-serif;&aquot;><span style=&aquot;font-family: ‘palatino linotype’, ‘new athena unicode’, athena, gentium, code2000, serif; font-size: 14.7px;&aquot;>μνημονικόν</span></span><span style=&aquot;color: #222222; font-family: sans-serif;&aquot;> — </span><em style=&aquot;color: #222222; font-family: sans-serif;&aquot;>искусство запоминания</em><span style=&aquot;color: #222222; font-family: sans-serif;&aquot;>), </span><strong style=&aquot;color: #222222; font-family: sans-serif;&aquot;>мнемоте́хника</strong><span style=&aquot;color: #222222; font-family: sans-serif;&aquot;> — совокупность специальных приёмов и способов, облегчающих </span><a class=&aquot;mw-redirect&aquot; style=&aquot;text-decoration-line: none; color: #0b0080; background-image: none; background-position: initial; background-size: initial; background-repeat: initial; background-attachment: initial; background-origin: initial; background-clip: initial; font-family: sans-serif;&aquot; title=&aquot;Запоминание&aquot; href=&aquot;https://ru.wikipedia.org/wiki/%D0%97%D0%B0%D0%BF%D0%BE%D0%BC%D0%B8%D0%BD%D0%B0%D0%BD%D0%B8%D0%B5&aquot;>запоминание</a><span style=&aquot;color: #222222; font-family: sans-serif;&aquot;> нужной информации и увеличивающих объём </span><a style=&aquot;text-decoration-line: none; color: #0b0080; background-image: none; background-position: initial; background-size: initial; background-repeat: initial; background-attachment: initial; background-origin: initial; background-clip: initial; font-family: sans-serif;&aquot; title=&aquot;Память&aquot; href=&aquot;https://ru.wikipedia.org/wiki/%D0%9F%D0%B0%D0%BC%D1%8F%D1%82%D1%8C&aquot;>памяти</a><span style=&aquot;color: #222222; font-family: sans-serif;&aquot;> путём образования </span><a style=&aquot;text-decoration-line: none; color: #0b0080; background-image: none; background-position: initial; background-size: initial; background-repeat: initial; background-attachment: initial; background-origin: initial; background-clip: initial; font-family: sans-serif;&aquot; title=&aquot;Ассоциация (психология)&aquot; href=&aquot;https://ru.wikipedia.org/wiki/%D0%90%D1%81%D1%81%D0%BE%D1%86%D0%B8%D0%B0%D1%86%D0%B8%D1%8F_(%D0%BF%D1%81%D0%B8%D1%85%D0%BE%D0%BB%D0%BE%D0%B3%D0%B8%D1%8F)&aquot;>ассоциаций</a><span style=&aquot;color: #222222; font-family: sans-serif;&aquot;> (связей): замена абстрактных объектов и фактов на понятия и представления, имеющие </span><a style=&aquot;text-decoration-line: none; color: #0b0080; background-image: none; background-position: initial; background-size: initial; background-repeat: initial; background-attachment: initial; background-origin: initial; background-clip: initial; font-family: sans-serif;&aquot; title=&aquot;Визуализация&aquot; href=&aquot;https://ru.wikipedia.org/wiki/%D0%92%D0%B8%D0%B7%D1%83%D0%B0%D0%BB%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F&aquot;>визуальное</a><span style=&aquot;color: #222222; font-family: sans-serif;&aquot;>, аудиальное или </span><a class=&aquot;mw-redirect&aquot; style=&aquot;text-decoration-line: none; color: #0b0080; background-image: none; background-position: initial; background-size: initial; background-repeat: initial; background-attachment: initial; background-origin: initial; background-clip: initial; font-family: sans-serif;&aquot; title=&aquot;Кинестетика&aquot; href=&aquot;https://ru.wikipedia.org/wiki/%D0%9A%D0%B8%D0%BD%D0%B5%D1%81%D1%82%D0%B5%D1%82%D0%B8%D0%BA%D0%B0&aquot;>кинестетическое</a><span style=&aquot;color: #222222; font-family: sans-serif;&aquot;> представление, связывание объектов с уже имеющейся информацией в </span><a style=&aquot;text-decoration-line: none; color: #0b0080; background-image: none; background-position: initial; background-size: initial; background-repeat: initial; background-attachment: initial; background-origin: initial; background-clip: initial; font-family: sans-serif;&aquot; title=&aquot;Память&aquot; href=&aquot;https://ru.wikipedia.org/wiki/%D0%9F%D0%B0%D0%BC%D1%8F%D1%82%D1%8C&aquot;>памяти</a><span style=&aquot;color: #222222; font-family: sans-serif;&aquot;> различных типов модификации для упрощения запоминания.</span></p>»]мнемонический[/itg-tooltip] [itg-tooltip href=»http://tooltip» tooltip-content=»<p><strong style=&aquot;position: relative; box-sizing: border-box; outline: none; resize: none; margin: 0px; padding: 0px; font-family: Fregat, sans-serif; border: 0px; font-variant-numeric: inherit; font-variant-east-asian: inherit; font-stretch: inherit; font-size: 17px; line-height: inherit; vertical-align: baseline;&aquot;>Акро́ним</strong><span style=&aquot;font-family: Fregat, sans-serif; font-size: 17px;&aquot;> (от греч. άκρος — «высший, крайний» и όνυμος — «имя») — аббревиатура, образованная из начальных букв слов или словосочетаний, произносимая как единое слово, а не побуквенно. Пример: «ГУМ» как </span><em style=&aquot;position: relative; box-sizing: border-box; outline: none; resize: none; margin: 0px; padding: 0px; font-family: Fregat, sans-serif; border: 0px; font-variant-numeric: inherit; font-variant-east-asian: inherit; font-stretch: inherit; font-size: 17px; line-height: inherit; vertical-align: baseline;&aquot;>гум</em><span style=&aquot;font-family: Fregat, sans-serif; font-size: 17px;&aquot;>, а не </span><em style=&aquot;position: relative; box-sizing: border-box; outline: none; resize: none; margin: 0px; padding: 0px; font-family: Fregat, sans-serif; border: 0px; font-variant-numeric: inherit; font-variant-east-asian: inherit; font-stretch: inherit; font-size: 17px; line-height: inherit; vertical-align: baseline;&aquot;>ГэУэМ</em><span style=&aquot;font-family: Fregat, sans-serif; font-size: 17px;&aquot;>.</span></p>»]акроним[/itg-tooltip], который содержит 5 принципов:

  1. S is for Single Responsibility Principle (Принцип единственной ответственности);
  2. O is for Open/Closed Principle (Принцип Открытости/Закрытости);
  3. L is for Liskov Substitution Principle (Принцип подстановки Барбары Лисков);
  4. I is for Interface Segregation Principle (Принцип разделения Интерфейса);
  5. D is for Dependency Inversion Principle (Принцип инверсии зависимостей);

И так, наша Азбука смерти, наш акроним расшифрован, погрузимся в каждый принцип детальнее.

Single Responsibility Principle (Принцип единственной ответственности).

Официальная формулировка, из-за которой хочется плакать: существует лишь одна причина, приводящая к изменению класса.

Фраза настолько туманная, что порождает больше вопросов чем ответов. Какая причина, зачем нам менять Класс, если мы работаем с экземплярами класса – объектами и пр.

Корректнее по моему и коллег опыту говорить об ответственности, или зоне ответственности: корзина, пользователь, администратор, плагины системы, работа с кешем, обработка запросов и ответов драйвера базы данных и пр.

Если хотите, это экранизация фразы «мухи отдельно, котлеты отдельно». Нужно семантически (или логически) разделять элементы архитектуры, не допуская пересечения функционала. Например, мы создаем бекенд для интернет-магазина с нуля (ну вот такие мы извращенцы) и нам нужно описать класс, отвечающий за работу корзины товаров. По сути нам нужен [itg-tooltip tooltip-content=»<p><strong>C</strong>reate <strong>R</strong>ead <strong>U</strong>pdate <strong>D</strong>elete, четыре базовых действия необходимых и достаточных чтобы управлять базой данных.</p>»]CRUD[/itg-tooltip], но для товаров :) Код на PHP будет выглядеть примерно так

<?php

class Cart extends Ecommerce {

    public function addToCart($data) {
        //
    }

    public function deleteFromCart($product_id) {
        //
    }

    public function getCartProducts() {
        //
    }

    public function cleanCache() {
        // wtf?!
    }

}

Рассмотрим приведенный выше код. Класс Cart (наследование класса Ecommerce не имеет тут логической нагрузки) содержит 4 своих метода addToCart(), deleteFromCart(), getCartProducts(), cleanCache(). Если первые 3 явно связаны с функционалом корзины, они добавляют, удаляют или возвращают товары, то 4-й cleanCache() чистит какой-то кеш в нашем системе, что можно считать нарушением принципа SRP, принципа единой ответственности.

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

Пример кода и разъяснения для JavaScript будут добавлены после официального релиза ECMAScript 2019.

Ihor Chyshkala

Пишу статьи про ИТ в свободное от работы время.

Оцените автора
Авторский блог Игоря Чишкалы
Добавить комментарий

Этот сайт использует Akismet для борьбы со спамом. Узнайте, как обрабатываются ваши данные комментариев.