Зачем нужно ООП?
==================

 Здравствуйте. Объясните пожалуйста, по вашему мнению, зачем нужно ооп? Чем оно полезно и чем оно нравится?  

Лично я - начинающая и работаю в лаборатории, где программирую только я одна, а остальные - учёные. Я можно сказать в свободном плавании, не считая учебников и курсов. Но на каждом углу я слышу, что ооп это просто насущная необходимость. Я пока такой необходимости не встретила - все логические части программы я легко и интуитивно выделяю в функции и всё выглядит красиво на мой взгляд. ООП же мне понять сложно. И если простые примеры из учебников выглядят достаточно ясно - допустим, есть класс животное, у него есть лапы и глаза, и в каждом объекте этого класса они определяются по-своему. Можно это вообразить и даже представить где это нужно.  

Но когда ты сталкиваешься с реальным проектом (пришлось знакомиться с фреймворком, завязанном на ооп и кодом с его использованием), то прелесть этой абстракции теряется - объект слишком сложный, чтобы его представить, непонятно что от чего наследуется где-то в недрах кода, всё по 100 раз переопределяется... Абстракция на абстракции на абстракции... Бесполезные функции, которые всё равно переписывать... Разве это упрощает задачу?  

А самое интересное, когда создаётся по классу на каждый чих/каждую запятую.  

Задаю вопрос не для разжигания хейта, но и не прошу учить меня жизни. Хочу попробовать понять точку зрения тех, кому это удобно и может что-то почерпнуть. 

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

Появилась мода на модульность.  

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

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

Раз все программы оперируют некоторыми данными, то нужно взять эти данные, взять функции (методы), которые работают с этими данными и поместить в один объект.  

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

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

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

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

 Разберитесь с разницей между ООП и процедурным программированием для начала.   

ООП в формулировке "Инкапсуляция, Наследование и Полиморфизм" может и не нужно.   

Объектно-ориентированный дизайн как инструмент декомпозиции нужен чтобы контролировать сложность системы.  
  

И вообще, вы хотите чтобы вам тут в двух словах разобрали тему многих книг и публикаций. Так не бывает.  
  

> то прелесть этой абстракции теряется - объект слишком сложный, чтобы его представить, непонятно что от чего наследуется где-то в недрах кода, всё по 100 раз переопределяется...

  

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

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

Впрочем, если вам этот ответ что-то даст:   

Цель ООП - управление сложностью ПО. 

 ООП задумывалось как подход для декомпозиции кода на модули — классы. Каждый класс выполняет свою функцию и код остаётся чистым. Это в идеале. Но в реале, ООП устраняя сложности процедурного программирования, добавляет свои. Всё как вы и описали. Идеи, описанные в книжках, в реальных примерах не имеют применений. Для написания хорошего ООП кода нужно много знать и хорошо понимать абстрактную сторону. Плюс, ООП реализовано множеством способов. Популярные реализации ООП (Java, C#) по-сути являются Класс-Ориентированным Программированием. Помимо этого ООП увеличивает объём кода. Также, постулаты на котором, основано текущее (популярное) ООП создают предпосылки для хрупкого кода. Например, наследование. Изначально наследование подразумевалось как метод для переиспользования кода. Но со временем стало понятно, что большие иерархии классов ведут к непредсказуемым ошибкам. Если обнаруживается ошибка в базовом классе при наличии уже большой иерархии, её исправление чревато появлением сложных ситуаций с падением модулей завязанных на него. Можно привести другие примеры, но это тема для целой статьи, а возможно и для нескольких. Сейчас в языки ООП внедряются фичи из функционального программирования. Функциональное программирование базируется на идее композиции функций. ООП сейчас переходит (или уже перешло) от наследования к композиции объектов. То есть рекомендуется использовать композицию вместо больших иерархий наследования. Функциональное программирование лишено проблем ООП. Многие вещи, которые в ООП надо специально изучать (например шаблоны проектирования, внедрение зависимостей), в ФП являются либо основополагающим принципом, либо естественно выплывающим следствием (в ООП тоже много хороших практик выплывают естественным образом, однако, чтоб понять их естественность приходится хорошенько вглядываться). ФП очень многое даёт из коробки. ООП — неплохая штука, однако оно отживает свой век. ФП позволяет с гораздо меньшими затратами писать надёжный, расширяемый, краткий, элегантный и эффективный код.  
  

Прошу не воспринимать моё отношение к ООП как негативное — у него есть свои плюсы, своя ниша. Плюс, в контексте ООП люди смогли изучить очень многое, ведь ООП навело их на многие мысли, создало необходимость в изучении структуризации и модуляризации кода. В контексте ФП это не было бы так очевидно (например, внедрение зависимостей в рамках ФП вообще не интересно изучать, так как в ФП — это просто передача параметров функции, то что мы итак понимаем). Так что всему своё место и время. 

 Низачем :)  
  

Если задача решается и без него. ООП - всего лишь инструмент и его нужно применять там, где его применение обоснованно. Если применять его не имеет смысла - не применяйте :) 

> Я пока такой необходимости не встретила

Все зависит от задач.  

Если я пишу в основном небольшие приложения, и не работаю в команде - мне ООП как бы нафиг не нужен.  

Но если код будет объемный и сопровождать его будет множество людей - без ООП это просто нереально. 

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

 Могу порекомендовать почитать [Гради Буча](http://kit.znu.edu.ua/iLec/9sem/OOP/lit/%5BBuch_G.%5D_Obektno-orientirovannoe_programmirovanie(BookFi.org).pdf). Он довольно наглядно объясняет, что это такое и зачем. 

 Все очень просто.   
**Представь наш мир, который НЕ поделен на объекты:**  
  

Представь, например, автомобиль, у которого двигатель приварен к кузову, генератор приварен к двигателю, а колеса приварены напрямую к ступичному узлу. Как ты колесо поменяешь? Да в общем-то никак.  
  

Представь, например, строение компьютера, где всё железо - это один монолитный блок. Допустим, у тебя повредилась какая-нибудь незначительная деталь - разъем для USB. Всё - компьютер за 50 круб в помойку?  
  

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

Так же и в программировании. Большая задача разбивается на подзадачи, бизнес-логика компонуется по объектам, что обеспечивает для разработчиков простоту поддержки и "долговечность" такого кода. 

 ООП применяют в enterprise потому что это легче тиражировать, поддерживать и продавать.  

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

В лабораториях вроде превалируют С и Fortran, когда нужно действительно что нибудь посчитать.)) 

 Абстракции являются способом добавить системе модульности. Потому что требования к (крупной) системе постоянно меняются. Тут заменяемость и расширяемость - важные факторы. Обычно это еще называют "гибкостью". Привязываться к конкретным имплементациям - очень быстро выходит боком. Поэтому все на абстракциях, даже там где они возможно не нужны. Но поскольку инженер не знает, что заказчик захочет завтра - сразу все заворачивает в абстракции. Отсюда появляется масса кода который просто поддерживает эту расширяемость. Поэтому когда смотришь на конечный продукт и на тот код из которого он сделан, думаешь это ведь можно было уместить в 100МБ, а у нас система на 6 Гб. Да, если конечный алгоритм отлить в железе он будет компактным но не будет расширяемым. Это "цена" за возможность внесения корректировок в систему, не переделывая систему целиком. 

 ООП нужно когда у нас есть набор данных разных типов которые хочется обрабатывать в совокупности как один. Вот и все 

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

Проблема "в учебнике все понятно, а в реальном коде непонятно" мне знакома, тоже с таким сталкивался в самом начале. Загвоздка тут в том, что надо перестать сопоставлять объекты в ООП с реальными объектами материального мира. Это абстракции, а примеры с кошечками и собачками дают для того, чтобы было проще читателю все это представить. На самом деле объект - это что угодно, что можно выделить в предметной области в виде чего-то самостоятельного и обособленного.  

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

 Во-первых, стоит перестать бояться писать избыточный код.  

Да, ООП вынуждает описывать классы, делать конструкторы, деструкторы. Но это все служит для более легкого понимания кода человеком. Не нужно экономить каждый байт в исходниках. Чем более ясно у вас описан код (например, переменные называются не i, j, k, а value, count, capacity), тем лучше. Также и с классами, глаз привыкает к структуре, что вот описание данных, вот рядом функции, которые эти данные инициализируют, работают с ними и уничтожают их.  
  

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

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

 Меня щас тапками закидают, но!  

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

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

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

Есть у нас на одном проекте, легаси с классами старше моей мамы(шутка), там все как раз по такому принципу и построено.  
  

Все внутренние методы, собраны в класс ради того что бы использовать его как сказано выше, не более того(и я честно не назвал бы это ООП, вот вообще, но что делать, работаем с тем, что есть).  
  

В целом, это наверное самое простое и того, чем и как можно было бы описать ООП(хотя это не точно). 

 Собственно, на каком языке пишите, какой фреймворк рассматривали, какой класс вас так испугал?  

Юзаите ли IDE, чтобы ориентироваться по классам? Наверно во всех джетбрейновских идешках курсор на вызываемый метод (this->method()) и Ctrl+B помогают найти место, где он реализован, например.  
  

- программирую только я одна  

- пока такой необходимости не встретила - все логические части программы я легко и интуитивно выделяю в функции и всё выглядит красиво на мой взгляд  
  

Ну и работайте на функциональщине, в чем проблема? Единственно, как бы все потом переписывать не пришлось. Или все-таки нужен фреймворк, а его нихарошие разрабы написали не правильно, на ООП? Просто удобное познается в сравнении с неудобным. Если проект не такой большой, то можно и без ООП прожить. Хотя, не вижу никаких сложностей в инструменте, позволяющим добавить больше структуры и порядка. Метод це функция в классе. Она подобна функции вне класса, только в классе. Переменные и классы объеденные, структурированы по какой-то логике. Разве этого не достаточно, чтобы юзать ООП? Помимо всяких паттернов, изоляции сложности и реализации методов и т.д.  

> объект слишком сложный, чтобы его представить, непонятно что от чего наследуется где-то в недрах кода, всё по 100 раз переопределяется... 

  

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