ООП и с чем его едят?

 Публичный пост

Привет Клуб
Сегодня хотел поговорить на тему объектно-ориентированное программирование. Сколько языков программирования не учил(ну да, приходилось учить большое количество), то всегда было сложно с восприятием данной парадигмы программирования

Вопрос
Кто может посоветовать или рассказать, зачем оно, привел примеры из настоящих примеров, а не вот это:

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

25 комментариев 👇

Окей, люблю объяснять что-нибудь на пальцах. Совсем по-простому, колхозно. Я специально опущу всякие паттерны и прочее (для тех, кто увидит пересечение с терминами :)) )

  1. У тебя есть фабрика по производству стульев, на которой вкалывают 8/5/2 человечки. У них есть всякие чертежи-снипы-планы. Эт, типа, и есть класс. Ничего нет произведённого, но есть описание всего :)
  2. Начали стул за стулом производить - это то, что называется инстансами стульев, либо объектами классов.
  3. Припёрло, значит, к стулу пятую ногу приделать, потому что сидушка под весом покупателей начала слишком часто, по отзывам, проламываться. Но у тебя же уже есть стул, да? Просто добавь к своим чертежам ещё бумажку, чтобы описать, как надо ставить пятую ногу в центр, и начни выпускать апгрейженные стулья. Это наследование.
  4. Каждый твой стул внутри имеет э.. Ну, положим, модуль gps-а, чтобы отслеживать местонахождение стула. Он глубоко внутри, совсем внутри, прям в деревяшке. Доступ к нему ты можешь получить только по кнопке, что закреплена снизу сидушки :) Включить и выключить, скажем. Это то, что называется инкапсуляцией: внешний интерфейс для получения того, что нельзя извне достать )
  5. Внезапно стулья проапгрейдились (снова наследование вышло) и научились ну, скажем, летать. Кто-то умеет летать по дуге, кто-то - только вертикально, кто-то - только вверх ножками, неважно. Это всё новые разновидности стульев, которые могут flight() :) Это и есть полиморфизм. Все умеют одно и то же, но по-разному.

Что там ещё..? Абстрактный класс? Ну, сидушка есть, а ножки каждый сам накорячит, как хочет. Вдруг ты захочешь венский стул или телескопические? Сидеть на сидушке, как на стуле, низя, значит только брать и делать своё (абстрактный класс не может иметь инстансов без наследования) :)

Как-то так.

Зачем всё это? KISS, DRY, SOLID и прочие страшные слова, которые говорят только об одном: пиши так, чтобы то, что ты пишешь, можно было потом переиспользовать где-то ещё без тотального кровьКишкиПереписываниеДедлайн. Реальный мир представлен нам в форме объектов, поэтому, описывая нечто текстом, мы можем декомпозировать это так, чтобы оно подходило целому пулу систем в виртуальном :)

  Развернуть 1 комментарий

Класс - описание
Обьект - производство
Наследование - добавление (апгрейд)
Инкапсуляция - доступ к обьектам(ай ай ай, если кто-то лезит "левый"
Полиморфизм - 1 интерфейс и много реализаций
Абстракция - способ представления объекта в программе

  Развернуть 1 комментарий

Именно так :)
...Господи, вот оно то самое чувство, когда ты такой передал мысль, другой тебя понял, а ты прям "оу ес" :))

  Развернуть 1 комментарий

@Cls, Есть такое) спасибо за объяснение 😉

  Развернуть 1 комментарий

Эх, вот бы в универе сразу так объясняли :D
Хотя, всё равно не уверен, что прям сразу бы стало понятно, тк по моему опыту надо раз 10-15 почитать/услышать объяснение ООП, чтобы самому понять

  Развернуть 1 комментарий

@Programistich, с инкапсуляцией не все так просто. Сокрытие данных не тождественно инкапсуляции. Первично, в инкапсуляции, на примере тех же стульев, что данные и методы "входят в комплект". У стула есть шестигранник для сборки. Не надо искать шестигранник у деда в шкафу. Но, при желании вы можете это сделать. Ровно как и взять шестигранник из набора стула для другой мебели, но фабрика умывает руки от последствий.

  Развернуть 1 комментарий
Михаил Семиколенов, разработчик электронной бюрократии 20 июля 2020

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

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

Собственно, к чему я все это - нужно просто брать и писать крупные системы (не обязательно что получится, главное сам факт), и понимание ООП просто придёт само.

А сейчас, наверное, просто не ясно зачем это всё, и дело не в том что аналогии непонятные, а в том что нет связи "причём тут вся эта мутотень и живой код чтобы кнопочка нажималась", это решается опытом.

P. s. Мне помогало в изучении, когда в школьные годы я замахивался на проекты сильно выше головы - большие игры, большие веб приложения. Ничего такого даже близко не мог написать, но пока искренне пытался (невежество не давало осознать истинную сложность задачи) - очень многое понимал в процессе.

  Развернуть 1 комментарий
Anna, Программист 19 июля 2020

Если честно, кроме книжки про паттерны ничего в голову не приходит. Там Java и паттерны с примерами применения. Мне она показалась не особо полезной, но я нахожу объектно ориентированный дизайн интуитивно понятным и легко могу спроектировать любое приложение на уровне заменяемых блоков.

Скорее всего книжками прокачать ООП не получится, нужна практика.

Я почти не имею опыта работы с Java, но знаю что C# построен на единой иерархии типов. По нему довольно легко понять как примерно все это должно работать. Стоит посмотреть на .NET классы, интерфейсы и попробовать сделать что-нибудь свое.

  Развернуть 1 комментарий

@Doredel, Я решил что мой основной язык будет котлин + андроид дев; поэтому хотелось понимать на адекватном уровне и писать самому код, а не гуглить 24/7

  Развернуть 1 комментарий

@Programistich, гугл занимает примерно 75% времени любого разработчика. Еще 20% это совещания и оставшиеся 5 делятся на распитие кофе и бренчания по клавиатуре.

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

  Развернуть 1 комментарий

@Doredel, Это понятно, но все же)
В моей ситуации это просто гуглинг еври минут

  Развернуть 1 комментарий

@Programistich, когда изучаешь новую технологию - это совершенно нормально.

  Развернуть 1 комментарий

@Doredel, Ну не совсем новую) но вообще да, не понимаю пока как практиковать котлин

  Развернуть 1 комментарий

Не стоит недооценивать паттерны проектирования.

Некоторые из них действительно интуитивно понятны потому, что уже есть в стандартных библиотеках разных языков (такие как, например Iterator, Composite или Abstract Factory).

Остальные, возможно для кого-то менее интуитивные, но от этого не менее полезные.

Лично я еще люблю паттерны за то, что снижают коммуникационные издержки: если два программиста знают о паттернах, то достаточно, например, сказать одному другому "здесь подойдёт декоратор" и дальнейшие обсуждения не нужны.

И меня очень печалит, когда приходится тратить часы времени на объяснение сеньору, что для обхода (и преобразования в различные форматы) абстрактного синтаксического дерева весьма удобен паттерн Visitor.

  Развернуть 1 комментарий

@hackman, знать паттерны - конечно полезно. Дело в том, что ими довольно легко выстрелить себе в ногу. Особенно когда впервые знакомишься - хочется везде их повставлять. Потом над твоим кодом неделями сидят матерые программисты по 20+ лет стажа и пытаются понять дичь, написанную на стратегиях.

Для новичка лучше просто посмотреть как основные принципы ООП работают, чем заучивать паттерны.

  Развернуть 1 комментарий

@Doredel
Разумеется во всём нужна мера :)

В моей практике были как over-engineered проекты, где на каждый чих была абстрактная фабрика, так и under-engineered, где 80% методов классов были статическими :)

Причём парадокс в том, что оба проекта были созданы сеньорами/архитекторами с 20+ летним стажем :)

  Развернуть 1 комментарий

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

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

  Развернуть 1 комментарий

В книге Head First Object Analysis and Design вполне доходчивое объяснение принципов ООП с примерами. Единственное, в книге сделан акцент на Java (хотя мне кажется это не критично).

  Развернуть 1 комментарий

Java знаю. Спасибо, почитаю

  Развернуть 1 комментарий
Егор Карташов, Sr. Infrastructure Engineer 20 июля 2020

https://www.coursera.org/learn/programming-languages-part-c - очень толковый разбор что за классы такие и зачем нужны, для лучшего понимания желательно пройти предыдущие две части, оно того стоит

  Развернуть 1 комментарий

Очень плюсую, все три в сумме -- один из лучших курсов вообще.

  Развернуть 1 комментарий

Что тут важно понять прежде всего не что, а для чего: ООП - это просто один из способов структурировать код.

Структурируя код, мы преодолеваем сложность системы; мы представляем ее в виде слоев абстракций, каждая из которых не слишком сложна. Для этого нам нужно как-то спрятать ненужные в каждом конкретном слое детали. Здесь нам поможет инкапсуляция.

Вторая, не менее важная задача - постараться написать как можно меньше кода; для этого его нужно использовать повторно. Здесь нам поможет полиморфизм.

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

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

Вторая задача решается через организацию типов в иерархию таким образом, чтобы всякий раз можно было бы использовать менее абстрактный тип там, где контракт определяет более абстрактный. Например, если функция "нарисовать" принимает класс "фигура" в качестве аргумента, а классы "круг" и "квадрат" являются подклассами класса "фигура" - то в функцию можно передать как круг, так и квадрат.

  Развернуть 1 комментарий

@EduardSurov, Спасибо! Ещё более понятно стало)

  Развернуть 1 комментарий

Да отведет судьба от меня гнилые помидоры!

Прежде всего попробуй разобраться что такое и для чего нужны инкапсуляция и полиморфизм. Это ключевые понятия ООП. Наследование это исклбчительно способ реализации полиморфизма, наследование это про систему типов, способ ее построить.
Потом почитай вот этот пост Фаулера про Tell, son't ask.
Потом посмотри как все эти очень умные советы можно воплотить в жизнь, потому что это нифига не очевидно.
Это есть вот тут:


И в блоге Егора Бугаенко. (Но упаси тебя боже читать там что-то на другие темы).

А я может пост наваяю а то писал коммент, а получилось уже дофига.

  Развернуть 1 комментарий

Как писал старина МакКонел: «Главный Технический Императив Разработки ПО - управление сложностью»

Человек не может помнить всё, в институте нас учили, что продавец на память может "вспомнить" что-то порядка 1000 позиций.

ООП помогает во-первых, увеличить количество абстракций, тем самым снизить количество сущностей задействованых в операции, и во-вторых, структурировать код. И то и другое благотворно сказывается на когнитивных затратах и экономии мыслетоплива.

  Развернуть 1 комментарий

😎

Автор поста открыл его для большого интернета, но комментирование и движухи доступны только участникам Клуба

Что вообще здесь происходит?


Войти  или  Вступить в Клуб