воскресенье, 28 июля 2013 г.

ПМО ИУС — ООП — Абстрагирование и типизация

Изначально мне и нам преподносили ООП с теоретическом стиле Буча — программные системы становятся все сложнее, понятие сложности, с этим надо что-то делать, … К этому всему эволюция программных парадигм (формулы, алгоритмы, подпрограммы, модули, …). Как показывала практика, понимание и усвоение с такой подачи шло очень слабо. По моему мнению, это происходило из-за ряда причин: приличный кусок теории, не связанной с практикой (просто большой объем такой информации воспринять и переварить сложно); отсутствие у студентов опыта написания и понимания сложных систем; новизна большого числа понятий, которые появлялись на практически пустом месте.

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

Для решения данных проблем было предпринято ряд действий. Во-первых, все ООП было аккуратно распилено на 6 разных частей (абстрагирование, типизация, модульность, наследование, иерархия, полиморфизм). Каждая часть — это отдельный пункт, с которым надо отдельно разобраться, а разбор проходил в виде отдельной лекционной части, не залезая в другие. Аналогичное деление происходило в лабораторных — когда в каждой из них акцент ставился на определенные моменты. Во-вторых, вся история появления ООП была выброшена из потенциальных конспектов и преподнесение делалось как есть (как создать класс, что такое объект, как можно эти оперировать, какие преимущества и недостатки). В-третьих, психологически практически полностью выброшен пугающий подтекст (сложность, большие системы, …), т.е. да, ООП может показаться и оказаться сложным, но ничего сложного в нем нет. В-четвертых, в материале были выброшены все малые детали, а акцент был только на больших сущностях, которые прокручивались по нескольку раз на разных лекциях (важно первое приближение, а детали уже в случае частных вопросов). В-пятых, материал не только как есть, но вокруг него ряд вопросов-ответов (почему так; зачем; что это дает; как это сделать; вот аналогичный в жизни пример, но не на языке С++; когда применять а когда воздержаться;…).

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

Абстрагирование и типизация

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

Мы с раннего детства умеем абстрагировать, но не знаем, что это так называется (; Если у нас есть корзинка фруктов и мы хотим узнать сколько там яблок, то для этого нам нужно провести абстрагирование. У нас есть задача (посчитать количество яблок), мы представляем что такое яблоко (можем его отличить от другого предмета в корзинке), умеем считать (ответ — число). Мы выбираем только те сущности и свойства реального мира, которые важны в нашей задаче. Нам важны только яблоки, и только их число. Нас не интересуют груши и грибы, нам не интересны спелые ли яблоки или червивые, нам важны только яблоки и только их число. Выделение нужных свойств из всего разнообразия — есть готовое абстрагирование.

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

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

  1. Кот Васька регулярно охотится на воробьёв в своём дворе. При чём после удачной охоты запирает воробьёв в клетку до конца сезона.

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

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

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

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

  3. Когда варкается, хливкие шорьки превращаются в мюмзиков. При чём за один такой день - одно превращение. Если не варкается, то количество мюмзиков увеличивается на 2. В зависимости от погоды каждый день варкается или нет.

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

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

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

Следующие шаги — каркас уже готов (поля и интерфейсы методов), собирается функциональность и проверяется её работа. В этой работе нет никакой инкапсуляции (все в public), обязательна демонстрация доступа к полям и методам класса напрямую (чтение, запись, вызов). Кроме того, необходима сборка конструктора по умолчанию и конструктора с параметрами, задающего полное начальное состояние объекта, и, соответственно, проверка их работы. Все в одном cpp-файле, ничего лишнего (так как ещё тут есть SVN, консольная среда Builder считается новой).

Таким образом, акцент идет на абстрагировании и типизации (создание своего типа, первые шаги; другие элементы типизации позже), а фокус держится прежде всего на базовыя понятиях класса/объекта, объединения кода и данных, а также их применения.

Подробности

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

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

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

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

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

Создавать каждый раз новый объект с нуля неудобно. Чаще всего получается так, что мы имеем много лампочек с похожим поведением, но при этом каждая из них имеет свое состояние. В связи с этим удобно сделать некоторый шаблон, по которому штамповать лампочки. Так вот, таким шаблоном является класс, а объект — это уже конкретная лампочка.

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

Синтаксис в С++ для типов/переменных и классов/объектов аналогичен. Также можно создавать указатели определенного класса на объекты, массивы объектов определенного класса, присваивать один другому и др..

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

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

Пример иерархии классов и каков в ней смысл (общее объединяется и выносится наверх; это общее может быть как код, так и данные).

Примеры того, как это может быть в С++ (лучше в Real-Time с нуля) — просто пустой класс, добавление 1-2 полей, запись-чтение, добавление функций (методов), вызов функции, работа в контексте класса, две формы записи тела метода (внутри класса и вне), функции-помощники класса (объекты можно передавать как параметры).

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

Специальная функция перед уничтожением объекта — деструктор.


суббота, 27 июля 2013 г.

ПМО ИУС — Разработка через тестирование

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

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

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

Причинами появления именно Google Test являлись: наличие зоопарка фреймворков для юнит-тестинга (о чем жаловались сами гуглеры — каждая собака желает иметь свой велосипед) и выбор межплатформенного и документированного из них; изучение ещё одного инструмента; точное попадание в С++ и лаконичность инструмента; потенциал развития и поддержки фреймворка, а также его совместимость с основной IDE (Buidler). Google Test стал совместимым только с XE2, поэтому Google Test появился в курсе только в 2012 году.

Следует отметить, что изучение новых и различных инструментов являлось одним и больших фокусов всего курса. Т.е. важным пониманием является то, что многое сделано до нас, и что этим многим надо уметь пользоваться, понимать что есть много полезных вещей и не только самим языком программирования жив инженер. В частности, од этот фокус попадали Doxygen и SVN. На заре ещё думали прикрутить JIRA'у, но руки не дошли.

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

Удержание фокуса

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

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

Сам Google Test подключается тоже как externals, в проекте достаточно было прописать пути и за-include-ть фреймворк.

Подробности

Слайды.

Старт и приближение к TDD начинался с рассмотрения моделей разработки ПО. Водопад — сам каскад водопада, необходимость этапов и правила отката, область применения (детерминированные с точки зрения технического задания системы). Если правила меняются, то использовать водопад сложно.

Диаметрально противоположная модель — спираль. Пример использования спирали (первый цикл, прототип, тест, обратная связь с заказчиком, уточнение требований, проектирование, разработка, … цикл). Каждый виток спирали — малый водопад. Итерации быстрые, ориентированные на изменяющиеся требования. Необходимость выхода на первый прототип. Условия применения спиральной модели — изменяющиеся требования, быстрое развитие ПО, необходимость экспериментирования, …

Между ними — V-образная модель. Как делается гибрид, в чем он выигрывает (соответствие каждой цикловой V отдельному процессу), преимущества и недостатки.

Только сейчас идет переход к TDD. Общая постановка TDD, как по алгоритму он применяется (классика TDD).

Следующий шаг — Google Test. Как инструмент, облегчающий автоматизацию процессов, происходящих в TDD. Да, можно сделать все вручную, но уже есть готовое помогающее решение и мы его будем изучать.

Получение Google Test и его подключение к проекту, рассказ на пальцах.

Простейший тест консольного приложения. Одиночный тест, EXPECT, ASSERT, EQ/NE/…, TRUE/FALSE, ….

Группы в Google Test. Зачем и что это такое. Порядок запуска тестов (или беспорядок (; ).

Выполнение теста как функции — любые дополнительные действия на С++.

Fixture-tests. Инициализация и завершение. Использование методов в служебных целях (контроль времени теста например).

Использование готовых Fixture.


пятница, 26 июля 2013 г.

ПМО ИУС — Оформление кода

Оформление кода начал внедрять ещё Андрей Логвиненко, но с этого времени прошел ряд изменений.

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

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

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

С точки зрения правил со временем от того, что было, осталась только основа — все редко используемые вещи даже не упоминались (потому что никто не использует в курсе например указатели на функции), некоторые произвольные шаги были сведены к одному (возможность выбора Egyptian brackets убрана в пользу на одном уровне вложенности, так как принять один жесткий вариант проще, чем наблюдать за винегретом и трудностью принятия решений). Кроме того, часть оформления была вынесена вне рамок первой лекции, а особенности сущностей, о которых не знали, упоминались позже по мере появления материала (например префикс «m_» появлялся и описывался только во время появления в лекциях первого класса с полем).

Doxygen, также как и оформление, был обязателен со второй л.р..

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

Удержание фокуса

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

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

Студенты вне графика (в обе стороны) — рафинирование комментариев (удаление бесполезных, акцент на задаче, пред-условиях и пост-условиях, а не на конкретной реализации, указание информации для внешнего пользователя, а не про себя, лаконичность, …).

Подробности

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

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

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

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

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

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

Венгерская нотация придумана давно и живет в недрах MS. Так как это было давно, то было важно наличие типа в имени. Типов может быть много, и в больших проектах это тяжело поддерживается и входит из-под контроля. Кроме того, с повышением структуризации кода, применением IDE и проверки типа на уровне компилятора необходимость указания типа резко падает, в связи с этим в высокоуровневых языках типизация такого рода происходит реже.

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

Сравнение c Lower Case. В последней отсутствует тип (облегчение работы с кодом), все буквы в нижнем регистре (облегчение восприятия и отсутствие неоднозначностей и ошибок при двух регистрах).

Использование префиксов и постфиксов в Lower Case по широкополосным служебным целям. Например указание типа «_t» ускоряет принятие решения при создании переменной по умолчанию, а также отличает принципиальное качество тип и переменная.

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

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

Систем автоматического генерирования документации много, Doxygen одна из них.


четверг, 25 июля 2013 г.

ПМО ИУС — Системы контроля версий

Исторически все развивалось так, что системы контроля версий были добавлены в курс ~ в 2008-м году, когда ещё не было Git'ов, Mercurial'ов и пр., а SVN занимал 90% рынка новых стартующих проектов. Subversion уже длительное время использовался в «Интервэйле» (как минимум с 2004 года) и этот опыт напрямую переносился. Кроме того, система организации каталогов проектов и подключения библиотек была взята в определяющем так, как это было организовано в компании.

По теме была запланирована одна лекция, которая обычно длилась 1-1.5 пары. Это была первая тема, так как все, что делалось в дальнейшем, делалось под контролем SVN.

SVN-сервер находился на кафедральном сервере и студенты имели доступ к нему из любой точки ВУЗа. Каждый из учащихся получал свой репозиторий, с которым он работал в течение семестра. На лабораторных в подавляющем числе случаев использовался интерфейс TortoiseSVN.

Удержание фокуса

Каждая лабораторная должна быть в конце зафиксирована в репозитории в виде тега и это проверялось при сдаче. Приучаем к отработке всего цикла — checkout, правки одной малой задачи, commit с описанием что было сделано. Для многих действий нужно было делать все в первых работ step-by-step, что, зачем, как.

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

Установка под контроль сразу же после появления исходных файлов. За контроль EXE/OBJ/… давать по рукам и заставлять снимать из под контроля.

Подробности

Слайды.

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

Сначала рассмотрение понятия проекта — нечто с определенной целью в виде некоторой активности в течение времени. Подготовка к вечеринке, выполнение курсового, поход на рыбалку, регулярная уборка в доме — все это проекты (будущий проект в svn).

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

Если рассмотреть проект во времени, то его состояние постоянно изменяется по мере выполнения каких-либо действий. Таким образом проект не просто набор чего-то, а что-то, что существует и изменяется во времени (будущий контроль проекта svn во времени).

С точки зрения контроля проекта во времени у нас могут возникать вопросы: в каком состоянии был проект в момент X? кто сделал действие Y? что изменялось в проекте за месяц Z? что надо сделать, чтобы отменить изменения за позапрошлую неделю? Данные проблемы надо как-то решать, и решение зависит от организации контроля проекта во времени (будущие типичные задачи при работе в svn).

Как мы можем контролировать проект во времени? Завести блокнот, создать ряд каталогов на диске, держать в голове, … у каждого способа есть свои достоинства и недостатки (блокнот копировать сложно но он надежный, компьютер доступен не всегда, но он быстр, в голове можно и забыть, но это всегда под рукой).

Так что такое системы контроля версий? Это вспомогательные инструменты, помогающие автоматизировать описанный выше процесс, тем самым уменьшить количество ошибок, предоставить удобные функции и др..

С точки зрения автоматизации уже имеются всем знакомые системы контроля версий, которые помогают нам в этом. Undo/Redo в где угодно (хоть в MS Word), страница в википедии (показываем в онлайне историю правок с датами, комментариями, возможностями сравнения и отката, …). Таких ресурсов много — история изменений одного файла в Dropbox, изменения страниц в pbworks.

И только теперь на сцену выходит Subversion и начинаются слайды.

Понятие архитектуры клиент-сервер. Хранилище одно, оно надежное и доступное отовсюду. Клиентов много, они общаются с хранилищем и сами себе буратины.

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

Понятие ревизий в Subverison. Ревизии атомарные, инкрементируются только при успешном commit'e. Каждая ревизия — в идеале одна отдельная задача.

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

Фиксация изменений (commit). Инициирует клиент, дает описание изменений. Все хорошо — фиксируется, плохо — не фиксируется (требуется ручное вмешательство при слиянии, проблемы подключения, …). Описание изменений ассоциируется с ревизией и потом может быть использовано.

Обновление (update). Использование когда возможны внешние правки (например работа в команде).

Откат локальных изменений (revert). Команда отрабатывает локально, без подключения к серверу. Локально всегда хранится копия с последнего checkout'a или update'a, чтобы система знала, что было исправлено локально, и чтобы можно было таким образом откатить изменения.

Понятие контроля файлов в WC. SVN должен знать, что ему контролировать, т.е. каждый файл на диске находится под контролем SVN или нет. Если мы сами создаем файл, то SVN о нем ничего не знает, и при необходимости мы должны ему сказать. Под контроль ставятся только исходные, но не производные (EXE, OBJ, …) файлы. Команды установки код контроль и снятия из-под контроля. Копирование и перемещение в SVN — не создает нагрузку на сервер.

Структура хранилища с точки зрения классики SVN — trunk, tags, branches. Что такое trunk, зачем нужны теги (фиксация стабильной версии, передача конкретной версии заказчику, выделение версии для конкретных работ, …). Понятие branches — выделение отельных веток и слияние (один программист пилит новую функциональность, второй правит баги, и оба друг другу не мешают; отдельные ветки для подпроектов и подзадач, когда требуется дальнейшее развитие).

Описание полного типичного рабочего цикла (checkout, updaten commit).

Свойства в SVN, на примере svn:externals. Подключение внешних ресурсов через externals (иначе не получится), экономия места, переключение externals на другую версию.

По обстоятельствам — демонстрация создания svn-сервера и типичных действий над hello world.


среда, 24 июля 2013 г.

ПМО ИУС — Содержание курса


Планирую сделать некоторое описание содержания курса на последний из семестров с выкладками того, почему было сделано так и какие имели место особенности. Букв получается много, поэтому распилено на несколько сообщений. Сначала — общее содержание.
Системы контроля версий
Изучение систем контроля версий в общем, практическое изучение Subversion на всем протяжении курса.
Оформление программного кода, системы автоматической генерации документации.
Общие вопросы оформления (зачем, когда, как), практическое изучение на всех лабораторных кроме одной, + также все под Doxygen.
Разработка через тестирование (Test Driven Development)
Спектр от водопада до спирали, использование Google Test с полным функциональным тестированием на всех лабораторных, кроме 2-х.
Объектно-ориентированное программирование
Последовательно, теоретически и практически, с периодическим повторением — абстрагирование, типизация, модульность, инкапсуляция, наследование, полиморфизм.
Rapid Application Development
GUI интерфейс на практической основе C++ Builder, изучение базовой событийной системы в Builder (который выглядит как однопоточный Reactor).
Исключения
Традиционные способы обработки исключительных ситуаций (игнор, останов, общая функция, возврат кода ошибки), исключения как инструмент, создание своих классов исключений и исключения сторонних библиотек на примере std::exception и исключениях среды C++ Builder.
Структуры данных
Разбор понятия структур данных. Линейные структуры данных: массив, стек, очередь, списки (разные). Деревья, бинарные, балансировка деревьев, способы обхода. Куча (heap). Динамическая и статическая реализация (линейных, деревьев, кучи). Хэш. Пример экзотической структуры данных — Sparse Array с инициализацией элементов только по требованию. (здесь без лабораторных)
STL
Основные понятия библиотеки: контейнеры, итераторы, алгоритмы (только). Разбор vector, list, stack, queue, priority_queue, deque, map, multimap, set, multiset, heap. Несколько алгоритмов.
Потоки ввода-вывода
Общие понятия потоков, иерархия потоковых классов std::, буферизация, функции потоков и манипуляторы, ошибки потоков и файловые потоки.

Развитие проекта под Subversion в лабораторных (кликабельно):