пятница, 20 мая 2016 г.

Что такое ООП и шаблоны проектирования

Регулярно вижу посты от начинающих программистов по вопросу изучения и понимания Объектно-Ориентированного Программирования (ООП). Что-то вроде такого: “Подскажите, что почитать для изучения ООП ?”.

Ответ же обычно такой - почитайте Гради Буча (можно Тимоти Бадда)  и шаблоны проектирования от Эриха Гамма + сотоварищи. Могут добавить еще пару книг (причем они не сильно лучше выше предложенного) и на этом все советы заканчиваются.

Гради Буч написал хорошую книгу, она подробно вводит читателя в мир ООП, причем на мой взгляд, автор проделал колоссальную работу и постарался изложить свои знания хорошим и образным языком. Эти же слова я могу отнести к книге Тимоти Бадда.
Книга по шаблонам хоть и  написана более сухим академическим языком, тоже может использоваться в качестве справочника и при должном подходе позволяет получить массу интересного. Но ...

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

К самим “смесителям, щитам и к документации” претензий нет. Но вот чего еще нет, так это понимания ЗАЧЕМ ОНИ НУЖНЫ и ЧТО С НИМИ ДЕЛАТЬ ?

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

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

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

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

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

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

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

И все-таки - почему нет хороших книг по двум направлениям:
  1. Элементарное введение в ООП
  2. Задачи по ООП

Разберемся с пунктом номер один. Прекрасно помню, насколько мне был необходим механизм ООП, когда я писал дипломную работу и у меня был на тот момент только язык Фортран. Моделировать надо было движение нескольких объектов и это порождало огромное количество сложностей. Следущая версия программы (работа оказалась интересной и мне дали возможность ее продолжить) была написана уже с помощью языка Паскаль, где я мог использовать структуры, которые здорово облегчили мне жизнь. Когда же у нас появились машины, на которых был C++ - первый объектно-ориентированный язык (ООЯ) в моей практике, то все стало выглядеть еще более привлекательным и удобным. Я настолько естественно перешел от процедур в ООП, что не испытал больших проблем с пониманием.
Конечно же, я читал (и продолжаю читать) про ООП, изучаю новые концепции и конструкции, но вот сам переход от процедур к ООП был простым.

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

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

За годы практики и размышлений у меня сложилось пара мыслей по этому поводу.

Мысль первая - БЕСПОЛЕЗНО УЧИТЬ ООП БЕЗ ХОРОШЕГО ПОНИМАНИЯ ПОШАГОВОГО ПРОЦЕДУРНОГО ПРОГРАММИРОВАНИЯ.
Т.е. если вы пока еще не твердо понимаете, как написать вычислительную задачу по готовому алгоритму с использованием простых переменных, циклов, операторов условий и процедур, да что там - вы толком не понимаете, что это все такое - даже не пытайтесь понять ООП. Не выйдет.
Сейчас возможно некоторые скажут - автор не прав, закидать его помидорами, ООП даже проще, чем процедурное програмирование и т.д. и т.п.

Но я настаиваю - НИЧЕГО НЕ ПОЛУЧИТСЯ.

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

Почему я так думаю ? Если почитать большинство авторов (я сам это регулярно говорю), то самая главная мысль - весь мир, который мы моделируем в наших программах, состоит из объектов. Поэтому описание мира в объектах - это естественно. Значит и программа, которая ими управляет или их использует, будет проще и понятнее. И это утверждение является вполне разумным и правдивым.
После этого практически все новички вывешивают в своем мозгу лозунги типа: “Да здравствует ООП - давайте сразу его учить !!! Долой процедурные языки !!!”

И тут же все попадают в ловушку - они почему-то предполагают, что процесс управления объектами происходит сам собой и не требует усилий.

НИЧЕГО ПОДОБНОГО !!!

Управление этими объектами может быть весьма сложным и происходит ПО ШАГАМ, которые выполняются в определенной последовательности. Каждый шаг - это выполнение команды. Команда для своего исполнения может использовать объекты, а может использовать что-то другое - например, обыкновенные числа или символы. Сложить два числа и положить результат в переменную - это тоже команда. И не менее важная, чем обращение к объекту.
Именно исполнение шагов/команд в определенной последовательности ведет нас к решению задачи. Будь эта програма хоть трижды объектно-ориентированная.

И еще раз - ПРОГРАММА РАБОТАЕТ ПО ШАГАМ, КОТОРЫЕ ВЫПОЛНЯЮТСЯ В ОПРЕДЕЛЕННОЙ ПОСЛЕДОВАТЕЛЬНОСТИ.
И если вы этого не уяснили - какое тут ООП ? Прежде всего вам надо понять, что программа (даже написанная как ООП) требует для правильного исполнения ОПРЕДЕЛЕННОЙ ПОСЛЕДОВАТЕЛЬНОСТИ ШАГОВ. И эта последовательность шагов выстраивается этими самыми циклами, условиями и переменными. Процедуры помогают структурировать эту последовательность, помогают не утонуть во всем этом коде и помогают  повторно использовать одинаковые фрагменты.

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

Мысль вторая - ПЕРЕХОД ОТ ПРОЦЕДУРНЫХ ЯЗЫКОВ К ОБЪЕКТНО-ОРИЕНТИРОВАННЫМ ДЕЙСТВИТЕЛЬНО ПРОСТ, КОГДА ЭТО ОЧЕВИДНЫМ ОБРАЗОМ ВЫТЕКАЕТ ИЗ РЕШАЕМОЙ ЗАДАЧИ.

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

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

Жду вас на бесплатных вебинарах - подробнее на Бесплатные вебинары. Присылайте заявки на цикл вебинаров “Что такое ООП и шаблоны проектирования”.

2 комментария:

  1. Глубочайший респект за блестящую статью! Преподаю ООП многие годы - за все, что сказано поднимаю обе руки!!!!

    ОтветитьУдалить