Введение
Вызовы первого курса
Факультеты информатики во всем мире продолжают спорить, как лучше учить началам программирования. Это всегда было трудной задачей, но новые вызовы добавляют новые проблемы:
- адаптация к всевозрастающей конкуренции;
- идентификация ключевых знаний и навыков, которым следует учить;
- внешнее давление и модные увлечения;
- широкий разброс начальной подготовки студентов;
- выбор примеров и упражнений;
- введение в реальные проблемы профессионального ПО;
- введение формальных методов, не отпугивающих студентов.
Адаптация к всевозрастающей конкуренции. Готовя профессионалов с прицелом на будущее, мы должны учить надежным, долговечным навыкам. Недостаточно давать им непосредственно применяемые технологии, для которых в нашей глобальной индустрии всегда найдутся дешевые программисты, доступные повсюду.
Идентификация ключевых знаний и навыков, которым следует учить. Программирование больше не является редким, специализированным умением. Многие люди занимаются различными элементарными формами программирования, например, написанием макросов, разработкой веб-сайтов, используя Python или ASP.NET. Специалистам программной инженерии необходимо больше, чем умение программировать; они должны управлять разработкой ПО с профессиональной тщательностью и тем самым отличаться от программистов-любителей.
Внешнее давление и модные увлечения. Очень важно сохранять холодную голову, невзирая на моду и внешнее давление. Мода непременно присутствует в нашей отрасли, и это не всегда плохо — структурное программирование, объектная технология и проектирование по образцам были когда-то модными. Мы должны убедиться, что идея прошла проверку временем, прежде чем испытывать ее на наших студентах. Справиться с внешним давлением — семья, окружение студентов — бывает более трудно. От нас требуют, чтобы мы учили специфическим технологиям, рекламируемым, позволяющим получить хорошо оплачиваемую работу. Но что если это направление ошибочно, и четыре года спустя появится новое направление, а старое будет забыто, и потребуются люди, умеющие решать проблемы, а не обладающие специфическими знаниями? Это наша обязанность: служить настоящим интересам студентов и их семей, обучая их фундаментальным предметам, позволяющим не только получить первую работу, но и продолжить успешную карьеру.
Достаточно глупа навязчивая идея, что после обучения резюме должно быть заполнено модными словечками - из страха не получить работу. Мировой феномен состоит в том, что на протяжении десятилетий у хорошего разработчика ПО нет проблем с поиском хорошей работы. Нет конца новым захватывающим предложениям в нашей области, несмотря на все мрачные прогнозы, распространяемые средствами массовой информации, после схлопывания "интернет-пузыря" и опасений, что все работы ушли в Индию, Бангалор... Но важна квалификация. Люди, которые получили и сохранили работу, - это не узко мыслящие специалисты, обучение которых сводилось к заголовкам сегодняшнего дня; это компетентные разработчики, обладающие широким и глубоким пониманием информатики, владеющие многими дополнительными технологиями.
Широкий разброс начальной подготовки студентов. Различие в начальной подготовке студентов усложняет задачу. Среди студентов, пришедших на первую лекцию вводного курса, можно найти тех, кто редко пользовался компьютером, и тех, кто уже строил коммерческие сайты, и все разнообразие между этими полюсами. Что может сделать преподаватель в такой ситуации?
- Заманчиво отобрать подготовленных студентов и учить только их, но тогда отсеиваются те, кто не имел возможности или склонности работать с компьютером. По моему опыту, среди них есть те, кто позже могут стать прекрасными исследователями благодаря склонности к абстракции и увлечению математикой приоритетно перед компьютерами.
- Не следует впадать и в другую крайность — всех поставить на нижний уровень и там начать работать. Нужен способ захватить и удерживать внимание более опытных студентов, позволяя им использовать и расширять достигнутые преимущества.
Есть надежда, что повторно используемые компоненты могут быть решением проблемы. Дав студентам доступ к библиотекам высокого качества, мы позволяем новичкам, благодаря абстрактным интерфейсам, воспользоваться преимуществами их функциональности, без понимания внутреннего устройства. Более продвинутые и любопытные студенты могут, опережая других, начать копаться во внутренностях компонентов и использовать их как образцы для своих собственных программ.
Выбор примеров и упражнений. Для того чтобы так работать, необходимы примеры высокого качества. Студенты, живущие сегодня в мире, наполненном чудесами мультимедиа, ожидают, что они начнут строить нечто большее, чем программы из джентльменского набора: "Постройте седьмое число Фибоначчи". Мы должны соответствовать ожиданиям "Поколения Nintendo", не допуская, конечно, чтобы технологический блеск затмевал обучение профессиональным навыкам.
Вариант этой проблемы - так называемый феномен Google: "Найти и приклеить" ("Google-and-paste"). Вы даете упражнение, требующее решения, скажем, объемом в 100 строк кода. Интернет-зависимые студенты быстро находят на каком-нибудь сайте код, решающий проблему, - с той лишь разницей, что найденное в Интернете решение содержит 10000 строк кода, поскольку в Интернете решается более общая задача. Конечно, можно запретить пользоваться Интернетом или отбраковывать найденные там решения. Но ведь "Найти и приклеить" - это одна из форм повторного использования, хотя и не совпадающая с рекомендуемыми в учебниках формами работы. Подход, применяемый в этой книге, делает шаг вперед. Мы не только одобряем повторное использование, но и обеспечиваем большое количество кода (150000 строк Eiffel к моменту написания этого текста) для повторного использования и для подражания. Код доступен в исходной форме и явно спроектирован как модель хорошего проекта и реализации. Повторное использование - одна из лучших практик, поддерживаемая курсом с самого начала, но в форме, согласованной с принципами программной инженерии и основанной на абстрактных интерфейсах и контрактах.
Введение в реальные проблемы разработки профессионального ПО. На университетском уровне подготовки специалистов по информатике или программной инженерии нельзя учить программированию "в малом". Мы должны готовить студентов к тому, с чем имеют дело профессионалы, — программированию "в больших размерах". Не все приемы, пригодные для малых размеров программ, масштабируемы. Сама природа академического окружения, особенно на начальном уровне, затрудняет подготовку студентов к реальным проблемам промышленного ПО. Разработка таких программных систем ведется большим коллективом, содержит много строк кода, ориентирована на различных пользователей, сопровождается в течение многих лет, подвержена многочисленным изменениям. Использование студентами предоставленных им больших библиотек в определенной степени снимает эти вопросы.
Забота о масштабируемости придает особую важность последней проблеме: введение формальных приемов, не отпугивающих студентов. Советы или приказы студентам использовать сокрытие информации, контракты и принципы инженерии программ — для начинающих могут восприниматься как бесполезные заклинания. Введение основанных на математике формальных приемов, таких как аксиоматическая семантика, может только расширить пропасть между студентом и преподавателем. Парадоксально: те студенты, кто уже немного программирует и, казалось бы, мог бы извлечь пользу из таких указаний и приемов, большей частью отвергают их, поскольку они знают по собственному опыту, что, по крайней мере, для небольших программ можно достичь приемлемого результата без всяких строгих правил. Лучший способ привить методологические принципы — это прагматично показать на деле, как это помогает сделать нечто, что в противном случае было бы немыслимо. Доверие к мощным библиотекам повторно используемых компонентов возникает тогда, когда они дают возможность, например, построить программу большой выразительной силы с графикой и анимацией. С самого начала курса студенты могут создавать важные приложения, визуальные, с различными эффектами. Результат достигается благодаря повторному использованию компонентов, определяемых абстрактными интерфейсами. Но они никогда бы не продвинулись далее нескольких классов, если бы должны были предварительно читать весь код.
Вместо восхваления абстракции, сокрытия информации и контрактов лучше позволить студентам использовать эти приемы и осознать, что методики работают. Если идея спасла вас от проблем, вы не станете отвергать ее как бесплодный теоретический совет.
Извне - Внутрь: Обращенный учебный план
Порядок тем в курсе программирования традиционно идет снизу вверх: все начинается с введения переменных и присваивания, затем идут управляющие структуры и структуры данных, и далее двигаемся, если время позволяет, к принципам модульного программирования и методике структурирования больших программ.
Этот подход дает студентам хорошее практическое понимание процесса создания программ. Но он не пригоден для обучения концепциям конструирования программных систем, которыми должны владеть инженеры ПО для успеха в профессиональной работе. Способности создавать программы больше не достаточно: многие разработчики, не являющиеся профессионалами, успешно могут выполнять эту работу. Профессионала отличает владение системными навыками разработки и сопровождения больших и сложных программ, адаптируемых к новым потребностям и открытых для повторного использования компонентов системы. Начинать с элементов нижнего уровня, как это рекомендуется в стандарте учебного плана "CS1", возможно, не лучший путь.
Вместо традиционного порядка "снизу вверх" или "сверху вниз" эта книга предлагает порядок "извне — внутрь". Он исходит из предположения, что наиболее эффективный способ обучения программированию состоит в использовании хорошего существующего ПО, где определение "хорошее" предполагает высокое качество кода и, что не менее важно, программных интерфейсов (API). Обучение на образцах во многом сводится к имитации проверенных временем моделей.
Изначально студенты получают мощное ПО: множество библиотек, называемое Traffic, где верхний слой написан специально для этой книги, а базисные слои (структуры данных, графика, GUI, мультимедиа, анимация ...) широко используются в коммерческих приложениях. Исходный код всех библиотек открыт, позволяя тем самым рассматривать его как хранилище качественных моделей, допускающих имитацию их студентами. На практике, по крайней мере, на первых порах, студенты используют это ПО в своих программах через спецификации API, называемые также контрактами (contract views). Основываясь на контрактах, в которых информация абстрагирована от реального кода, студенты могут строить интересные приложения, даже когда написанная ими часть состоит из нескольких строчек, в которых вызываются модули библиотеки. Прогрессируя в процессе обучения, они начинают строить более сложные программы и идут "внутрь", понимая устройство вызываемых модулей — открывая и изучая устройство "черных ящиков". К концу курса они должны уметь самостоятельно строить такие библиотеки.
Результатом стратегии "Извне — Внутрь" является "Обращенный учебный план", когда студенты начинают как потребители готовых компонентов, становясь по мере обучения производителями. Это не означает игнорирование в обучении концепций и навыков нижнего уровня — в конечном счете, наша цель научить студентов заботиться обо всем, что требуется при создании ПО, начиная от общей картины до мельчайших деталей. В нашем подходе большое внимание уделяется архитектурным навыкам, которыми зачастую пренебрегают в подходе "снизу — вверх".
Этот подход нацелен на то, чтобы студенты могли владеть ключевыми концепциями программной инженерии, в частности, абстракцией. В моей карьере в индустрии я многократно наблюдал, что главное качество, выделяющее профессионала, — это способность к абстракции, умение отделять главное от второстепенного, долговременные аспекты — от преходящих, спецификацию — от реализации. Все хорошие учебники ратуют за абстракцию, но результат этих призывов будет слабым, если студенты знакомы с программированием только как с набором небольших примеров на реализацию алгоритмов. Я также могу прочесть лекцию про абстракцию, но наиболее эффективно будет сослаться на пример, показав студентам, как можно создать выразительное приложение благодаря повторному использованию существующего ПО. Наше ПО является большим по академическим стандартам, изучение его исходного кода заняло бы месяцы. И все же студенты могут уже в первую неделю курса строить нетривиальные приложения, используя знание контрактов.
Абстракция здесь — не просто прекрасная идея, не уговоры быть хорошими и все делать правильно. Это единственный путь достижения желаемой цели, стоя на плечах гигантов. Студенты не нуждаются в рассуждениях о пользе абстракции и повторного использования, если с первых шагов и повседневно они приобретают основанный на контрактах опыт построения мощных приложений благодаря повторному использованию библиотек. Для них эти концепции становятся второй природой.
Обучение лучше, чем молитва, и если есть нечто лучше обучения, то это демонстрация принципов работы, осуществленная самими студентами. Сделайте так — и услышите "Вау!".
Поддерживающее ПО
Центральным для подхода, представленного в этой книге, является ПО Traffic, доступное для свободной загрузки на сайте http://touch.ethz.ch.
Выбор области приложения для поддерживающей библиотеки должен отвечать ряду требований.
- Предметная область должна быть знакома всем студентам так, чтобы они могли проводить время в изучении решений, хорошо понимая проблему. Было бы интересно рассмотреть, например, астрономию в качестве предметной области. Но тогда, боюсь, больше времени пришлось бы потратить на обсуждение комет и галактик, чем на наследуемые структуры и инварианты классов.
- Проблемная область должна обеспечивать большое множество интересных алгоритмов, примеров структур данных, применение фундаментальных концепций, позволять преподавателю создавать новые примеры, помимо тех, что приведены в книге. Наши коллеги, обучающие алгоритмам, распределенным системам, искусственному интеллекту и другим разделам информатики, должны иметь возможность при желании использовать ПО для решения собственных задач.
- Выбранная тема должна требовать применения графики и средств мультимедиа, предполагать продвинутый графический интерфейс пользователя.
- В отличие от многих видеоигр, наша продукция не должна содержать жестокости и агрессии, неприемлемых для университетского образования.
Проблемная область, выбранная нами, — транспортная система города: моделирование, планирование, имитация, отображение, статистика. Библиотека Traffic — это не просто приложение, выполняющее определенную работу, это библиотека классов, обеспечивающая повторно используемые компоненты, из которых студенты и преподаватели могут строить приложения. Она содержит элементы ГИС (Географической Информационной Системы) в более скромном варианте, поддерживая, тем не менее, механизмы графического отображения.
Как пример, эта книга использует Париж с его улицами и транспортной системой. Так как описание города представляется отдельным файлом в формате XML, можно без труда перейти к любому другому городу с его транспортной системой. На второй неделе обучения несколько студентов ETH спонтанно подготовили файл, представляющий транспортную систему Цюриха, который с тех пор и используется.
Самое первое приложение, которое строят студенты, содержит 12 строчек. При его выполнении отображается карта, подсвечивается Парижское метро на карте, выбирается предопределенный маршрут и визуализируется турист, следующий маршрутом, в стиле видеоигры с анимацией. Вот код этого приложения:
class PREVIEW inherit TOURISM feature explore — Показать город и маршрут. do Paris.display Louvre.spotlight Metro.highlight Routel.animate end end
Алгоритм включает только четыре оператора, выполняемых при работе программы, и все же его эффект выразителен благодаря механизмам Traffic.
Несмотря на доверие к содержанию существующего ПО, я стараюсь избежать ощущения "магии". Фактически все можно объяснить на подходящем уровне абстракции. Мы никогда не говорим: "делайте все, как я сказал. Поймете все позже, когда подрастете". Такое отношение не годится ни при обучении студентов, ни при воспитании собственных детей. В нашем примере даже предложение наследования inherit может быть объяснено простым способом. Я, конечно, не излагаю теорию наследования, но говорю студентам, что класс TOURISM является классом-помощником (helper class), в котором вводятся предопределенные объекты, такие, как Paris, Louvre, Metro и Routel, и что новый класс может "наследовать" от такого существующего класса, получая доступ к его компонентам (features). Говорится также, что нет необходимости рассматривать детали класса TOURISM, но это можно сделать, если чувствуете в себе рождение "инженерного чувства", стремление выяснить, как это все устроено.
Правило, позволяющее студентам постепенно постигать суть, всегда абстрактно и обходится без обмана.