пятница, 9 сентября 2016 г.

[prog.memories] Путь к ООП как осознанная необходимость...

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

На первом курсе универа нам преподавали программирование в рамках всего одного предмета, емнип, "Методы и средства конструирования программ". На Pascal-е. Сначала на Robotron 1715 без жестких дисков и 64K памяти, где мы использовали Turbo Pascal 3.0. Затем на IBM XT (и из аналогах -- EC1840/1841), уже с винчестерами, 640K RAM и Turbo Pascal 5.0-5.5. В качестве лабораторных очень простые вещи -- методы решения уровнений, сложение/перемножение/обращение матриц, методы сортировки и тому подобное.

И вот к концу первого курса я решил повыпендриваться и в качестве лабораторки по теме "Работа с текстовыми файлами на языке Pascal" вызвался сделать не больше, не меньше, но нормальный экранный текстовый редактор. Под "экранным" понимался обычный многострочный текстовый редактор, в котором передвигаешься по тексту стрелками, вводишь и удаляешь текст в любом месте. В общем то, что было в том же самом Turbo Pascal. Или в редакторе Norton Commander-а.

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

В общем, для реализации этого редактора очень многое пришлось делать с нуля самостоятельно. И работу с клавиатурой (через BIOS), и работу с экраном (через чтение/запись видеобуфера), и менюшки, и диалоги, и, естественно, сам редактор. Полная перекомпиляция проекта занимала около 45 секунд. При том, что Turbo Pascal компилировал код с очень приличной скоростью (что-то порядка 500 строк в секунду), это означало, что я наколбасил приблизительно 20K строк кода. Для тогдашнего Pascal это было не сложно, язык ну очень уж многословный.

Что мне довольно быстро стало мешать, так это наличие функций с большим количеством аргументов. А т.к. нам уже объяснили в чем достоинства структрного программирования без goto и глобальных переменных, то протягивания состояния выполнялось через аргументы функций. По мере разрастания кода некоторые функции, внутри которых выполнялись какие-то сложные действия, стали получать под 10 аргументов и даже больше. Со временем это стало проблемой. Хорошо еще, что в Pascal-е была статическая типизация и очень шустрая компиляция. Поэтому, если в какую-то функцию требовалось добавить еще один параметр, то довольно быстро обнаруживались все куски кода, которые подлежали правкам.

Т.к. писать большие программы никто не учил, пришлось на ходу переизобретать то, что уже было известно. Связанные по смыслу аргументы объединялись в структуры (например, координаты и размеры окна, которые раньше задавались четырьмя параметрами -- x, y, cx, cy, стали упрятываться в одну структуру Rectangle). Что позволило существенно уменьшить количество аргументов в функциях. А это очень упростило работу с кодом.

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

Текстовый редактор я, в итоге, сделал. Лабу сдал. И переключился с Pascal-я на C. Довольно быстро выяснилось, что C -- это совсем другой мир. Не такой теплый и уютный, как Pascal. Понятие "отстрел ноги" стало ощущаться практически на физическом уровне :)

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

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

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

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

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

Комментариев нет: