Основы объектно-ориентированного проектирования

         

Бесшовная разработка


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

Выгоды от бесшовного подхода многочисленны:

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

Бесшовность и обратимость


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



Этапы и задачи


Жизненный цикл каждого кластера включает следующие этапы:

спецификация: идентификация классов (абстракций данных) кластера и их главных особенностей и ограничений;проектирование: определение архитектуры классов и их отношений;реализация: завершение классов во всех деталях;верификация и Аттестация (Verification & Validation): контроль классов кластера (статическая проверка, тестирование и другие методы);обобщение: подготовка к повторному использованию (см. ниже).

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

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



Кластерная модель жизненного цикла ПО


Общая схема разработки, известная как Кластерная Модель, приведена на рис. 10.3. Вертикальная ось представляет последовательный компонент процесса: чем ниже размещена та или иная работа, тем позже она будет выполнена. Горизонтальное направление отражает параллельную разработку: задачи на одном уровне могут выполняться в одно время.

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

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


Рис. 10.3.  Кластерная модель жизненного цикла ПО

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

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



Рис. 10.4.  Кластеры проекта как множество уровней абстракции

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


Кластеры


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

Кластер - это группа связанных классов или связанных кластеров (рекурсивное определение).

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

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

Кластеры не являются супермодулями. Ранее мы привели аргументы против введения подобных единиц, например пакетов, вместо этого сохраняется единственный модульный механизм - класс.

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





Обобщение


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

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

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

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


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

Даже если дополнительные ресурсы предусмотрены, то только этого недостаточно. Залогом успеха служит комбинация усилий a priori и a posteriori:

Культура повторного использования

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

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

Этап обобщения может содержать следующие действия:

Абстрагирование: введение абстрактных классов там, где это необходимо.Факторизацию (Factoring): распознавание первоначально несвязанных классов, которые являются фактически вариантами того же самого понятия, так что для них можно ввести общего родителя.Добавление утверждений, особенно постусловий и инвариантов, отражающих углубленное понимание семантики класса и его особенностей.


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

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


Обратимость: мудрость иногда расцветает слишком поздно


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

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

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

Это явление отражает поговорка - esprit de l'escalier, ("лестничное остроумие", остроумие задним числом). Вообразите приятный обед в фешенебельной парижской квартире на третьем этаже. Со всех сторон звучат остроты по поводу телятины Marengo, а Вы будто онемели. Суаре заканчивается, Вы попрощались с хозяевами, спускаетесь по лестнице и вдруг - вот она, разящая остроумная реплика, которая сделала бы Вас героем вечера! Но слишком поздно.

Имеют ли место приступы esprit de l'escalier в программном обеспечении? Они существуют с тех пор, как стали замораживать спецификацию прежде, чем приступить к решению. Плохие менеджеры подавляют программистов - пишите код и помалкивайте. Хорошие менеджеры стараются использовать в своих интересах запоздалые идеи спецификации, не обращая внимания на то, кто отвечает за данную проблему, и невзирая на требования стиля водопада.

С развитием OO-разработки стало ясно, что явление esprit de l'escalier - не только результат лени при анализе, но и отражение самой природы процесса разработки ПО. Мудрость иногда приходит слишком поздно. Нигде более, чем в объектной технологии, не проявляется так явно связь между проблемой и решением. Не только потому, что мы иногда понимаем аспекты проблемы только в процессе решения, но и по более глубокой причине. Решение воздействует на проблему и может предложить лучший функциональный подход.

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

Введение обратимости требует дополнить диаграмму жизненного цикла кластера указаниями на постоянную возможность обратных пересмотров и исправлений:


Рис. 10.5.  Жизненный цикл отдельного кластера, обратимость



Параллельная разработка


Одно из последствий деления на кластеры - уход от недостатков традиционной бескомпромиссной модели жизненного цикла ПО. Известная Модель Водопада, введенная в 1970 г., была реакцией против устаревшего подхода "раньше запрограммируйте, а потом опишите". Заслуга этого подхода выражается в распределении обязанностей, определении основных задач разработки ПО и в подчеркивании важности открытой спецификации.

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

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

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


Рис. 10.1.  Модель Водопада

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

Вот как выглядит жизненный мини-цикл разработки кластера:


Рис. 10.2.  Жизненный цикл отдельного кластера

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



У нас все - лицо


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

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

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

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

Следующая история, заимствованная из книги Романа Якобсона "Essays on General Linguistics", поможет поставить точку:

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

Так же обстоит дело с объектной технологией. У нас все - лицо!



Абстракция


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

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

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

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

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



Другие курсы


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



Филогенез и онтогенез


Когда следует начинать?

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

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

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



Курсы для аспирантов


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



Объектно-ориентированный план


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

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

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

Выбор разработки библиотеки в качестве проекта, объединяющего усилия факультета, дает несколько преимуществ:

Хотя проект рассчитан на длительную перспективу, частные результаты могут быть получены в короткие сроки.
Компиляторы и подобные разработки относятся к категории "все или ничего" - пока они полностью не завершены, их распространение скорее повредит вашей репутации, чем поможет ей. С библиотеками дело обстоит по-другому, даже десятка два качественных повторно используемых классов могут оказать потрясающую службу своим пользователям и привлечь к ним значительное внимание.Поскольку серьезная библиотека является большим проектом, то в ней найдется место для вклада многих людей - от хорошо подготовленных студентов до доцентов и профессоров. Предполагается, конечно, что правильно выбрана проблемная область, и она соответствует научным и другим ресурсам факультета или кафедры.Если говорить о ресурсах, то проект может начинаться достаточно скромно, но быть прямым кандидатом для привлечения внимания организаций, занимающихся распределением фондов. Он также может быть предложен тем компаниям, для которых интересна выбранная проблемная область.Построение хорошей библиотеки представляет привлекательную задачу, ставящую новые научные проблемы, так что выходом успешного проекта может быть не только ПО, но и публикации, диссертации. Возникающие при этом научные проблемы могут быть двух видов. Во-первых, конструирование повторно используемых компонентов представляет одну из наиболее интересных и трудных проблем инженерии программ, в решении которых метод оказывает некоторую помощь, но определенно не дает ответа на все вопросы. Во-вторых, любая успешная прикладная библиотека должна опираться на таксономию предметной области, требуя долговременных усилий в классификации известных концепций в этой области. Как хорошо известно, в естественных науках (вспомните обсуждение истории таксономии в лекции 6) классификация является первым шагом в понимании сути. Такие усилия, предпринятые для новой проблемной области, известные как анализ предметной области, поднимают новые и интересные проблемы.Предполагается возможность междисциплинарной кооперации с исследователями из различных областей приложения.Кооперацию следует начинать с людей, работающих в соседних областях.Многие университеты располагают двумя группами специалистов: одних, ориентированных на инженерию программ (часто "comliuting science"), других - на проблемы бизнеса (часто "information systems"). Независимо от того, разделены эти две группы или являются частями одной структуры, проект может быть привлекателен для обеих групп, обеспечивая возможность сотрудничества.Наконец, успешная библиотека, предоставляющая программные компоненты для важной проблемной области, может стать широко известной, принеся известность ее разработчикам.Можно надеяться, что в ближайшие годы появятся университеты, вдохновившиеся этими идеями и создавшие "Повторно используемые Финансовые Компоненты X Университета -" или "Библиотека ОО-Обработки Текстов Y Политехнического института". Имена у них будут красивее приведенных, но столь же известны, как в свое время UCSD Pascal, Waterloo Fortran и система X Window, разработанная в MIT.


Обращенный учебный план


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

цифровые системы, использующие VLSI и CAD;обратная связь, распараллеливание, верификация;линейные системы и управление;прием и передача энергии;устройства и технологии.

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



Политика многих семестров


Стратегия "от потребителя к производителю" имеет интересный вариант применения в курсах, ориентированных на приложения, таких как Операционные системы, Графика, Конструирование компиляторов или Искусственный интеллект.

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

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



Полный учебный план (curriculum)


Этот неполный список показывает возможности повсеместного применения метода, так что возникает ощущение, что вокруг него можно построить полный учебный план по специальности (software curriculum). Несколько организаций уже добились некоторого успеха в этом направлении. Нет сомнений, что кто-то может сделать прорыв и довести до сознания руководства университета, что следует идти по этой дороге.



Профессиональная подготовка (тренинг) в индустрии


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

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

Единственная стратегия, гарантирующая преодоление этой проблемы, состоит в следующем:

Начальный тренинг: стратегия "пройди его дважды"

T1 Пройди начальный курс.T2 Попытайся выполнить ОО-разработку.T3 Пройди начальный курс.

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

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

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

Принцип Темы Тренинга

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

Еще два принципа. Во-первых, не ограничивайтесь вводными курсами:

Принцип углубленной учебной программы

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

Принцип Тренинга Менеджеров

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


Менеджеры, независимо от уровня их технической подготовки, должны быть знакомы с основными ОО-идеями, уметь оценивать их влияние на распределение задач, организацию команды, жизненный цикл проекта, экономику разработки ПО. Жизненный цикл обсуждается в следующей лекции (основательно в книгах, ориентированных на менеджеров, таких как [Goldberg 1995], [Baudoin 1996] и [M 1995]).

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


Среднее и высшее образование


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

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

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

Вот курсы, которые могут получать преимущества от использования "тяжелых" или "легких" объектов. Операционные системы, где метод помогает освоить понятия процесса, парадигму обмена сообщениями, важность скрытия информации, четкого определения интерфейсов, ограничений коммуникационных каналов при проектировании подходящей архитектуры систем. Введение в формальные методы, Функциональное программирование, Логическое программирование, где упор должен делаться на связь с утверждениями. Введение в искусственный интеллект, где наследование является ключевым элементом представления знаний. Базы данных, где центральное место должно отводиться понятию АТД и обсуждению ОО-баз данных.

Даже на курс по архитектуре компьютеров влияют ОО-идеи: концепции модульности, скрытия информации и утверждения могут служить для представления материала ясным и убедительным способом.



Стратегия "от потребителя к производителю"


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

Разочаровывающий эффект многих курсов зачастую связан с тем, что преподаватели дают только простые примеры и упражнения, так что студенты не работают с реальными интересными приложениями. Можно ли получить удовлетворение от вычисления первых 25 чисел Фибоначчи или от замены в тексте одного слова другим - типичные примеры элементарного программистского курса.

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

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

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



Терминология


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

Под средним образованием будем понимать средние школы, лицеи, гимназии (High school (US), lyceum, Gymnasium).Высшее образование - первые несколько лет университета или их эквивалент (то, что называется "undergraduate studies" в США и других англо-саксонских странах, Gakubu в Японии). Во Франции и других странах, находящихся под влиянием ее системы образования, это соответствует комбинации классов preparatoires и первых двух лет инженерных школ или первому и второму циклу университетов. В системе образования Германии это соответствует Grundstudium. Термин высшее образование (undergraduate) будет использоваться ниже для этого уровня.Наконец, для последних лет образования (магистратура, аспирантура), заканчивающихся присуждением научных степеней, будем использовать термин аспирантура (graduate - в США, postgraduate - в Англии, DEA, DESS - во Франции, Hauptstudium - в Германии, Daigakuin - в Японии).

Ученичество


Стратегия "от потребителя к производителю" представляет применение к программистскому обучению техники, освященной временем, - ученичество. Ученик, отданный в обучение мастеру, учится, пока мастер не поймет, что техника подмастерья не хуже, чем у мастера. За отсутствием нужного числа доступных мастеров применимость такого способа (мастер - ученик) ограничена. Но, к счастью, нам не нужны сами мастера, достаточно иметь результаты их работы - повторно используемые компоненты.

Этот подход является продолжением тенденции, уже повлиявшей на обучение некоторым темам в программистском образовании, таких как конструирование компиляторов, еще до того, как объектная технология стала популярной. В семидесятых и в начале восьмидесятых годов типичный семестровый курс по компиляторам включал написание компилятора (интерпретатора) с нуля. Однако первые же задачи лексического анализа и разбора требовали столь больших усилий, что на практике компилятор мог быть построен только для игрушечного языка. Обычно дело не доходило до наиболее интересных вещей: семантического анализа, генерации кода и оптимизации. Когда же появился и стал широко применяться инструментарий для лексического анализа и разбора, такой как Lex и Yacc, то это позволило студентам тратить на эти задачи существенно меньше времени. Наша стратегия обобщает этот опыт.



Вперед к новой педагогике для программистов


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

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

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

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



Вводные курсы


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

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



Выбор языка


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

В языках, основанных на C, например, придется объяснять, почему массив и указатель следует рассматривать как одно и то же понятие - свойство, имеющее корни в технике оптимизации старой архитектуры компьютеров; на эти объяснения потребуется время и энергия в ущерб обучению понятиям проектирования программ. Более того, это ведет к тому, что студенты приучаются мыслить в терминах низкоуровневых механизмов - адресов, указателей, памяти, сигналов. Они будут тратить неоправданно много времени на борьбу с различными жучками в своих программах.

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

Главное качество языка, используемого во вводном курсе, это его структурная простота и поддержка ОО-идей: модульность, основанная на классах, проектирование по контракту, статическая типизация и наследование. Но не следует недооценивать роли синтаксической ясности. Например, тексты на C++ и Java наполнены строками, такими как:

public static void main(String[] args { if (this->fd == -1 && !open_fd(this)) if ((xfrm = (char*)malloc(xfrm_len + 1)) == NULL) {

Как видно, синтаксис этих языков, основанный на многих специальных операциях, затуманен и зашифрован.

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

Дэвид Кларк из университета Канберры на основе опыта обучения опубликовал некоторые из своих заключений в Usenet:

В последнем семестре я обучал студентов программированию, используя Java (вторые полгода из годичного курса для первокурсников). Из моего опыта следует, что студенты не находят язык Java простым в обучении. Неоднократно язык мешал мне учить тому, чему бы я хотел. Вот несколько примеров: Первое, с чем они сталкиваются, это главная программа с заголовком: public static void main (String [ ] args), выбрасывающая исключения вида IOException. Здесь в одной строке встречается 6 различных понятий, которые студенты не готовы воспринимать.Достаточно свободно можно осуществить вывод, но чтобы что-то ввести, потребуется попрыгать (import, declare, initialize). Единственный способ ввода числа с клавиатуры - это прочесть строку и разобрать ее. И снова с этим приходится сталкиваться уже на первой лекции.Java рассматривает примитивные типы данных (int, char, boolean, float, long, ...) не так, как другие объекты. Здесь есть их объектные эквиваленты (Integer, Boolean, Character и т. д.). Но нет связи между int и Integer.Класс String представляет специальный случай (для эффективности). Он используется только для строк, не меняющих значения. Есть также класс StringBuffer для строк, меняющих свое значение. Все прекрасно, но нет взаимосвязи между этими классами. Есть только несколько общих компонентов.Отсутствие универсальности означает необходимость преобразования типов, например, при использовании коллекций элементов, таких как Stack или Hashtable. Все это создает помехи для начинающих студентов и уводит их в сторону от главных целей обучения. Проф. Кларк далее сравнивает этот опыт с его практикой обучения с использованием нотации этой книги, о которой он пишет: "Я фактически не учил языку, помимо некоторых примеров кода".

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


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

Некоторые гибридные языки имеют индустриальную значимость, но им следует учить позднее, когда студенты овладеют базисными концепциями. Это не новая идея: когда в семидесятых годах факультеты информатики (computing science departments) приняли Pascal, они также включали специальные курсы по изучению Fortran, Cobol или PL/I, что требовалось тогда индустрии. Аналогично современный учебный план может включать специальные курсы по C++ или Java для удовлетворения требований индустрии, давая возможность студентам включать требуемые шумовые слова в свои резюме. В любом случае студенты лучше поймут C++ и Java после изучения объектной технологии, используя чистый ОО-язык. Начальный курс, формирующий сознание у студентов, должен использовать лучший технический подход.

Некоторые преподаватели пытаются использовать гибриды C из-за ощущаемого давления индустрии. Но этого не стоит делать по ряду причин:

Требования индустрии изменчивы. В какие-то годы все хотели что-то подобное RPG и Cobol. В конце 1996 все начали требовать Java, но еще в 1995 никто и не слышал о Java. Что же будет стоять в списке 2010 или 2020? Мы не знаем, но мы обязаны наделить наших студентов потенциалом, который будет востребован на рынке и в эти годы. По этой причине особое внимание следует уделять долговременным навыкам проектирования и разумным (intellectual) принципам.То, что мы начинаем обучать таким навыкам и принципам, вовсе не исключает обучения специфическим подходам. На самом деле, как отмечалось, скорее помогает. Студент, глубоко освоивший ОО-концепции, используя подходящую нотацию, будет лучшим C++- или Java-программистом, чем тот, для кого первая встреча с программированием включала битву с языком.Исторический прецедент с Pascal показывает, что преподаватели информатики могут добиться успеха, благодаря собственному выбору.В середине семидесятых годов в индустрии никто не требовал Pascal; фактически почти никто в индустрии и не слышал о Pascal. В те времена индустрия требовала одного из Трех Теноров - Fortran, Cobol и PL/I. В преподавании и в науке было выбрано другое решение - наилучшее техническое решение, соответствующее тому уровню, на котором находилась программистская методология - структурное программирование. Результат себя оправдал, студентов стали обучать абстрактным концепциям и техническим приемам разработки программ, подготавливая их к изучению новых языков и инструментария.

Вымощенная дорога к другим подходам


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

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