// codeart.ru / Теория программирования / В чем суть ООП Форум

В чем суть ООП rss подписка

Автор: Evgeniy Sergeev

В последнее время очень внимательно слежу за проектами одного популярного блогера с забавным ником Тормоз. Недавно он начал писать в ООП стиле и сегодня представил свой первый класс на всеобщее обсуждение. Поэтому, пользуясь случаем, хочу высказать пару соображений на тему «что такое ООП».

В первую очередь хочу пояснить причем тут код Тормоза. Все дело в том, что посмотрев на его код я сразу подумал о том, что в нем нет ничего от объектно ориентированного программирования. Почему? А вот почему.

Основу ООП — составляют такие понятие как класс и экземпляр класса (объект). Но при этом программа не становится объектно ориентированной только от того, что в ней появились классы. Гораздо важнее чтобы объекты взаимодействовали друг с другом. Именно взаимодействие делает ООП парадигму мощным инструментом. Поэтому, чем меньше класс и чем больше он открыт для взаимодействия — тем больше программа соответствует духу ООП (ИМХО).

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

// 1
upper_case("Some string");

// 2
"Some string".toUpperCase();

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

При написании программы в ООП стиле нужно избегать монстроподобных, монолитных классов — это закон. Нет. Правда! Гораздо лучше делать маленькие и мобильные классы, чем мучиться с большими. Например, в коде Тормоза все сбито в один класс — это и хранение данных, и управление ошибками, и сама бизнес-логика. Между тем, все это хозяйство можно разбить на три более мелких класса и заставить их взаимодействовать!

Я понимаю, что психологически сложно заставить себя писать маленькие классы. Ведь такой подход кажется неэффективным. Но на самом деле пользы от маленького класса гораздо больше чем вреда (об этом более подробно поговорим в следующем посте). При этом, конечно, не стоит терять голову и чувство меры.

Возвращаясь к заголовку топика хочу сказать: суть ООП — это взаимодействие классов, а не их наличие.

  1. Заметил за собой, что почти не различаю понятие класса и объекта. Для меня класс — это почти то же самое, что объект. Поэтому говоря про взаимодействие классов я имею в виду объекты.

  2. Ну различать особо и не требуется, хотя стоило бы. Объект — это детализация, так сказать, конкретика. Экземпляр класса.

    Насчёт ООП, так ведь объект, порождаемый моим классом как раз для взаимодействий и предназначен. Я же представил на суд не CMS какую-нибудь, где оправдано было бы взаимодействие многих классов. Это отдельный класс.

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

    В принципе, кэш действительно стоило бы вынести в отдельный класс, наверно… но тогда classAvisoPrefixes был бы от него зависим.

    В этом есть и плюсы и минусы.

  3. То есть я к тому, что в любом отдельном классе на самом деле ООП не так много — оно во взаимодействии объектов, не так ли?

  4. > но тогда classAvisoPrefixes был бы от него зависим.

    А в чем проблема? На самом деле от зависимостей никуда не деться, их просто нужно научиться правильно готовить. :-) В том смысле, что зависимости должны быть гибкими и продуманными.
    Я считаю удачно когда зависимость возникает от «популярного» класса. Т.е. есть такой класс, который используется во многих частях программы, тогда зависимость от него становится прозрачной. При этом, конечно, не должно возникать транзитивных связей!

    >То есть я к тому, что в любом отдельном классе на самом деле ООП не так много — оно во взаимодействии объектов, не так ли?

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

  5. >Ну различать особо и не требуется, хотя стоило бы. Объект — это детализация, так сказать, конкретика. Экземпляр класса.

    Для меня абстракция — это интерфейс :-). А конкретика — это и класс, и объект :-)

  6. Класс нужен для того, чтобы его удобно было интегрировать в самые различные решения, не заморачиваясь с особенностями реализации. А твоё мнение какое? )

  7. Тормоз, а чем тогда класс от модуля отличается? По мне таки модуль нужен для того, чтобы его везде можно было интегрировать. А класс — это строительная единица. Т.е. один класс — это одна сущность предметной области.

  8. Хм, ну в каких-то частных случаях ничем не отличаются. Хотя, мне бы ещё понять, что конкретно ты имеешь в виду, когда пишешь про модуль.

    Впрочем, в любом случае мы начинаем спорить о терминах, это не есть гуд. Класс — действительно строительная единица. И где противоречие? Мой класс тоже строительная единица. И я согласен, что возможно слишком агрегатированная она )

  9. Тормоз, твой класс — это контейнер для функций. Т.е. он вмещает в себя несколько сущностей, которые вполне могут существовать по отдельности :-)

  10. Можешь показать класс, про который нельзя сказать то же самое?

  11. class Integer{
    public function __construct($value) {
    $this->value = $value;
    }

    public function get() {
    return $this->value;
    }

    public function plus(Integer $n) {
    return new Interger($this->value + $n->get());
    }
    }

    $a = new Interger(5);
    $b = new Interger(1);
    $sub = $a->plus($b);

  12. класс Integer:
    1) имеет некое внутреннее состояние, которое характеризуется целым числом (по идеи нужно проверять, что в в конструктор передано целое число)
    2) он может взаимодействовать с другими классами типа Integer

  13. Замудрёно как-то и оторвано от жизни. Ну или я от неё оторван, раз не понимаю, зачем это нужно.

  14. Тормоз, у нас с тобой вообще разное понимание ооп. Поэтому и понять друг друга не можем

  15. — В чём суть верблюда?
    — Верблюда суть в песок!

    Нет сути у ООП. Это как смысл жизни. Жизнь есть, а смысла нет. Можешь его искать. Можешь найти на время или на всегда. Но всё же его нет.
    ООП — один из подходов разработки программного обеспечения. Можно говорить об эффективности его применения в том или ином контексте. Но сути у подхода нет.

    Буго-го-гашеньки :)

  16. Евгений, нет абсолютных истин когда речь идет о мнениях. У смысла нет абсолютного определения, так же как и у сути ООП. Поэтому каждый может трактовать их по-своему.

  17. Евгений, вы кстати не правильно понимаете слово суть.

  18. А я так радовался что в php (после javascript) нет этих «str».toUpperCase(). Гораздо интуитивно понятней, а главное, не надо задумываться, что строка — это объект, с ним можно производить какие-то действия (это понимание приходит через очень большое время после того, как прочитал про это в книжках).

  19. Evgeny, ладно. Думаю я вас понял. Но всё же бессмысленно говорить о сути ООП. Можно говорить о правильности применения подхода. В любом случае — это не маленькие классы. Размер скорее имеет значение для восприятия. :)
    На самом деле речь идёт об уровне абстракции. Евангелисты ООП рекомендуют, что бы класс реализовывал только одну функциональность (функциональность связанную с одной абстрактной сущностью). Безусловно он может для этого использовать другие сущности, количество которых ограничено глубиной абстрагирования. Для кого-то достаточно колеса, а кто-то выделит диск, камеру, покрышку, ниппель у камеры, болты крепления и т.д. И потом соберёт это в классе колеса. Стал ли класс колеса проще? Только за счёт скрытия реализаций каждого из под классов.

    Но здесь стоит отметить, что избыточная и не востребованная глубина абстракции может отнять время и не дать пользы. Простая реализация может сохранить время. Если же для колеса потребуется функционал смены резины, то тогда можно обратиться к нашему любимому рефакторингу и выделить класс покрышки. :)

    С другой стороны я соглашусь, что если в классе сразу напихано куча функционалов, то их лучше сразу абстрагировать. Уже одно чтение и тестирование кода облегчится.

  20. А вот в этом

    // 1
    upper_case("Some string");

    // 2
    "Some string".toUpperCase();

    я особой разницы не вижу. Здесь дело вкуса. Кому-то ближе функциональный стиль, а кто-то всё видит объектами. PHP всё же язык функциональный с ООП наворотами.

  21. Я тоже не вижу особой разницы, оба варианта не слишком-то красивы на самом деле ) Хотя второй, пожалуй, чуть удобнее.

  22. Евгений,
    > Евангелисты ООП рекомендуют, что бы класс реализовывал только одну функциональность (функциональность связанную с одной абстрактной сущностью)

    Так это и есть — «создавайте маленькие классы» :-)

    >Для кого-то достаточно колеса, а кто-то выделит диск, камеру, покрышку, ниппель у камеры, болты крепления и т.д. И потом соберет это в классе колеса. Стал ли класс колеса проще? Только за счет скрытия реализаций каждого из под классов.

    Это тоже «создавайте маленькие классы». Если для решения задачи достаточно абстракции уровня колеса, то создайте маленький класс «Колесо». Если потребовалось пойти вглубь, то создайте маленькие классы «нипель», «покрышка» (ну и т.д.) и включите их в класс колеса.

    >Стал ли класс колеса проще?
    Не знаю. Смотреть надо.

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

    И что? Я говорил противоположное? Или вы считаете, что если один класс разбить на два (без изменения конечного функционала), то изменится уровень абстракции?

  23. Я так и не могу понять, что есть маленький класс.

    Класс Zend_Date я так понимаю маленький?

  24. Маленький класс — это такой класс при разбиении которого на более мелкие части происходит ухудшение восприятия кода и усложнение логики программы.

  25. То есть, это нечто субъективно, что не имеет смысла обсуждать?

  26. Евгений, да это субъективно. Обсуждать смысла нет, надо попробывать и принять для себя решение.

  27. Че вы курили? ))

Leave a Reply

« »