Мировая индустрия по производству программных продуктов относительно молода, а тем более молода российская индустрия, по существу, сформировавшаяся лишь после зарождения рыночных структур. Несмотря на это, за последние несколько лет российские производители доказали, что они способны создавать продукты, пользующиеся спросом не только в России, но и за рубежом. Опыт одной из таких компаний, в плане организации процесса выпуска программных продуктов хотелось бы рассмотреть в данной статье.
Коллектив разработчиков обычно имеет свою отлаженную структуру организации труда и свои традиции в области программирования, и здесь вряд ли может существовать какая-то идеальная модель. Но как бы то ни было, основные этапы разработки продукта остаются одинаковыми для любого коллектива и любой задачи:
- Выработка целей и требований к предмету разработки
- Разработка предварительного (эскизного) проекта
- Разработка детального проекта
- Реализация
- Тестирование
Цели и требования
Разработка каждой программы начинается с определения целей - для чего фирме нужно создание этого программного продукта, и требований - какие функции должна выполнять данная программа.
Цели и требования формулируются совместно отделом маркетинга и отделом разработки; они определяют общую концепцию продукта, целевой сегмент рынка, приблизительные технические требования, преимущества перед конкурентами. Создавая свою продукцию, производитель должен учитывать зачастую противоречивые запросы множества пользователей. Например, новички часто обращались в отдел технической поддержки компании ABBYY с вопросом: "Куда делся toolbar в системе FineReader?" А дело было в том, что toolbar в FineReader 3.0 - настраиваемый, и перетащив на другое место или выведя за пределы экрана, человек его "терял". Опытные же пользователи хотели иметь возможность управлять настройками панели toolbar. Разработчики приняли компромиссное решение: в FineReader 4.0 toolbar можно передвигать в ограниченной области, что не дает возможности "потерять" toolbar и упрощает его подключение в случае нечаянного удаления.
Чтобы затраты не стали чрезмерными, а срок окончания разработки не отодвинулся на неопределенное время, необходимо выработать некие принципы определения компромисса, которыми можно было бы руководствоваться, принимая решения на различных этапах разработки. Эти принципы и определены в целях проекта.
Требования устанавливаются в зависимости от запросов потребителя. У Microsoft, например, имеется служба по работе с потребителями, сотрудники которой участвуют в составлении спецификаций на этапе выработки требований, а компания IBM может позволить себе проводить опросы тысяч пользователей. Обычно, практичность новых функций полагается проверять на первых тестерах прототипов. Но это весьма дорогостоящее мероприятие.
В ABBYY используется несколько каналов получения информации от пользователей: обратная связь от службы сбыта, от службы технической поддержки, изучение продукции конкурентов, анкетирование на выставках и в демонстрационных залах.
Разработка предварительного проекта
После определения целей и требований к программе начинается разработка предварительного проекта, описывающего внешний вид продукта, используемые технологии, алгоритмы и архитектуру системы. Это самый сложный и ответственный этап: именно сейчас принимаются принципиальные решения и определяется судьба будущего продукта, поэтому на проработку предварительного проекта отводится довольно много времени. Так, для создания системы OCR FineReader 3.0 он занял 5 месяцев, FineReader 4.0 - около полугода.
Архитектурно программа четко разделяется на программную оболочку (shell), реализующую интерфейс с пользователем, и механизмы (engines), реализующие содержательные действия, например, процесс распознавания. Подходы к проектированию этих двух типов подсистем отличаются, поскольку приходится решать разные задачи. Известно много методологий проектирования, каждая из которых имеет свои области применения. В отделе исследований и разработок ABBYY используются две взаимодополняющие методологии SADT (Structured Analysis & Design Technique) [3] и OOD (Object Oriented Design).
Предварительный проект программного продукта представляет собой описание архитектуры системы на верхнем уровне; система на данном этапе разбивается на подсистемы и определяются программные интерфейсы между ними. Например, система FineReader имеет подсистемы обработки изображений, анализа и синтеза документа, распознавания, лингвистической поддержки, сканирования и программную оболочку. На этом этапе используется методология OOD.
В ABBYY применяется нотация собственной разработки, которая отражает три типа отношений между объектами и классами: использование, наследование и владение. Разработчики ABBYY выделяют "владение" в самостоятельный тип отношений, хотя оно является частным случаем отношения "использование". Это обусловлено ориентацией на язык программирования C++, который в отличие от языка Eiffel в методике Мейера, не имеет автоматической сборки мусора.
При проектировании механизма на основании документа "Цели и требования к продукту" создается Функциональная модель системы (используется методология SADT) - основные функции из "Требований" разбиваются (декомпозируются) на элементарные. Предварительный проект пользовательского интерфейса - это картинки с описанием функции кнопок и пунктов меню. Кстати, зачастую детальный проект интерфейса не составляется из-за широкого использования стандартных классов и компонентов, к реализации приступают, имея предварительный проект. При разработке интерфейсов и форматов данных необходимо принимать специальные меры для обеспечения развития с сохранением совместимости. Стандартные способы обеспечения совместимости описаны в инструкции.
Одним из наиболее важных результатов предварительного проектирования системы является разбиение целой системы на отдельные подсистемы, после чего их можно разрабатывать параллельно. Выбор подсистем во многом базируется на минимизации связей между подсистемами - проектирование каждой подсистемы должно заключаться в самостоятельном определении средств, при помощи которых можно удовлетворить требования к входной информации, поступающей от других подсистем, и к информации, передаваемой из данной подсистемы на вход последующих.
Опыт разработчиков ABBYY показывает, что заниматься предварительным проектом должно не более двух человек, к обсуждению можно привлекать всех компетентных сотрудников.
Детальный проект
Цель детального проектирования - разработка архитектуры системы, которая реализует функции, описанные в предварительном проекте. После создания Функциональной модели можно было бы на каждую элементарную функцию написать отдельную процедуру и считать разработку законченной. Однако, если бы даже такая система в конце концов начала действовать, то она работала бы до первой попытки внести в нее изменения - ведь внесение функциональных изменений высокого уровня в подобные системы влечет за собой переделки на всех нижних уровнях, и стоимость таких доработок становится сравнимой со стоимостью всего проекта.
Чтобы этого избежать, в ABBYY применяется методология OOD, которая позволяет создавать устойчивые к изменениям программы, оперируя не функциями, а объектами - логически цельными, слабо связанными друг с другом частями системы. Объекты сконструированы так, что они практически "не знают" об устройстве друг друга, что позволяет вносить изменения даже на верхних уровнях.
Детальный проект содержит подробное описание структуры данных, основных объектов системы, их методов и атрибутов. Разработчики ABBYY используют стандартные, зафиксированные в инструкции, приемы решения различных проблем детального проектирования и способы оценки качества проекта. Тестирование детального проекта производят инженеры, которые будут заниматься дальнейшей реализацией. Хороший детальный проект и меры по обеспечению сопровождаемости исходных текстов служат гарантией безболезненного развития продукта в будущем.
Реализация
Следующий этап - реализация, разработка исходных текстов программы, которые прежде всего должны быть понятны и легко читаемы. Только в этом случае они будут сопровождаемыми. Основной способ обеспечить возможность чтения текстов - использование стандартизированных приемов программирования и оформления. В отделе исследований и разработок ABBYY требования к исходным текстам перечислены в "Инструкции программиста" - одном из первых документов, который изучают стажеры при поступлении на работу.
Поскольку срок жизни продуктов достаточно велик, и они существуют в течение многих версий, качество исходных текстов имеет большое значение. Руководитель группы проверяет их на соответствие формальным требованиям, а в критических для качества продукта или трудных для внешнего тестирования местах текст вычитывается содержательно (например, исходные тексты подсистемы распознавания в FineReader вычитываются почти полностью).
Тестирование
В ABBYY тестирование сопровождает каждый этап разработки программы:
- Тестирование проекта.
- Тестирование исходного текста.
- Тестирование готовой системы.
Проект вычитывается на предмет корректности, понятности и полноты. Исходный текст проверяется на предмет корректности и читаемости. Готовая система тестируется отдельной группой технического контроля по плану, утвержденному руководителем проекта, при необходимости используются автоматические тесты. План перечисляет выбранные методики тестирования и программу действий по каждой методике. Основные методики: тестирование соответствия возможностей программы описанию в проекте, тестирование на устойчивость, на качество работы, на легкость освоения неподготовленным пользователем, сравнительное тестирование с конкурирующими продуктами, тестирование пользовательской документации.
Организация труда
Обычно каждая программистская компания сама для себя решает задачу организации производства. Здесь не существует каких-либо книжных примеров, как создать идеальную профессиональную команду. Сколько компаний - столько и моделей. ABBYY cпециализируется на разработке "наукоемкого" программного обеспечения, поэтому разработка исходного текста программы - творческий процесс, а не формальный перевод спецификаций в исходные тексты. Проектирование и реализация обычно подразумевают использование стандартного набора решений, причем проверенных. В случае "наукоемких" систем алгоритмы часто приходится разрабатывать заново.
Как следствие, невозможна жесткая специализация инженеров на "проектировщиков" и "кодировщиков". Разработка технологий распознавания требует ясного представления о способах реализации этих технологий, поскольку именно эффективная реализация делает тот или иной подход применимым или нет. Что же касается лингвистических продуктов, то, как показывает опыт, лингвистов можно привлекать либо как экспертов, либо для подготовки словарных баз. Разрабатывать лингвистический продукт должны инженеры. Тем не менее ясно, что качество работы, к примеру, системы распознавания в первую очередь зависит от проектных решений, поэтому указанные трудности не должны приводить к отказу от структурирования процесса разработки.
Инженеры разделены на группы, в каждой от 2 до 6 человек. Группа работает над небольшим проектом или над подсистемой в большом проекте. Руководитель группы разрабатывает проект, ставит задачи, контролирует результаты и сроки. Если над проектом работает несколько групп, их координирует руководитель проекта, который разрабатывает предварительный проект системы в целом. Руководитель следит за графиком работ и вносит коррективы для согласованного завершения работы различными группами.
Инструментальные средства
Основным средством разработки является Microsoft Visual C++. Он достаточно сложен, но, с другой стороны, это единственный объектно-ориентированный язык общего назначения, удовлетворительно поддерживаемый основными поставщиками. Для С++ существует большое количество библиотек классов, поддерживающих создание пользовательского интерфейса, клиент-серверных приложений, работу с базами данных и т.д. Поэтому пока альтернативы C++ [4] нет. Для второстепенных проектов иногда используется Visual Basic. Язык Java рассматривался как альтернатива Basic, но из-за отсутствия визуального средства разработки форм он пока остается малопригодным.
Для обеспечения сопровождаемости продукта большое значение имеет система поддержки версий исходных текстов, которая обеспечивает групповую работу над проектом: параллельные модификации одной и той же программы, повторное использование кода, параллельные версии проекта. Этот инструмент позволяет проследить историю развития продукции определенного класса, понять смысл тех или иных технических решений.
Заключение
Мы рассказали об основных этапах разработки программного продукта на примере опыта российской фирмы. Еще раз хотим подчеркнуть, что описанная форма организации труда и выбора инструментария в большой степени присуща данной фирме и отвечает ее целям и задачам. Невозможность четкой формализации процесса разработки "наукоемкого" ПО не означает, что можно вообще отказаться от структуризации процесса разработки и вести проект по наитию. Опыт ABBYY показал, что чем больше порядка и системы в разработке проекта, тем лучше результат.
OOD - это метод разработки программных систем, который предполагает, что архитектура любой программы строится из модулей, определяемых типами объектов (классами) и отношениями между ними, а не функциями, выполняемыми данной программой. В книге "Object-Oriented Software Construction" Б.Мейер (Bertrand Meyer) [5] описывает проблемы разработки качественных программ, концепцию OOD и методики создания программ.
Из "Рекомендаций по проектированию архитектуры системы" компании ABBYY
Требования к разбиению на подсистемы
- Сильная логическая связь внутри подсистем и слабая между подсистемами. Это обеспечивает минимальные интерфейсы между подсистемами.
- Возможность независимой разработки подсистем отдельными бригадами
- Уменьшение зависимости от операционной системы и оборудования за счет использования сменных компонентов (драйверов)
- Возможность встраивания механизмов в другие продукты.
В языке С++ для указания на объект используются ссылки и указатели. Эти механизмы сильно перекрываются по области применения, но использование тех или других зависит от ситуации.
Из "Инструкции программиста" компании ABBYY
Использование ссылок и указателей
Отношение владения между объектами всегда описывается при помощи указателя. Не существует владеющей ссылки. Во всех остальных случаях ссылка предпочтительнее указателя по следующим причинам:
- В то время, как существует нулевой указатель, не существует нулевой ссылки. Это позволяет при работе со ссылками избежать излишних проверок.
- Применение ссылки позволяет избежать ошибок использования адресной арифметики.
- Выражения при работе с ссылкой получаются короче.
Если объекту нужно иметь доступ к другому объекту, который за время жизни первого объекта не будет уничтожен или заменен, то нужно запоминать в первом объекте константную ссылку на второй объект. Это будет указывать на неизменность второго объекта за время жизни первого. Если объект, на который указывают, нужно заменять, в качестве поля используется указатель, а методы доступа могут возвращать ссылку. Применение указателей и ссылок в параметрах функции Если в качестве параметра не нужно передавать нулевой указатель для обозначения пустого объекта, лучше использовать ссылку. Это облегчает чтение кода функции и позволяет избежать излишней проверки на равенство указателя нулю.
Если сравнивать разработку "наукоемких" программ и информационных систем (по затратам на производство среди различных категорий ПО на первом месте стоят информационные системы, большинство программистов в мире занимается разработкой и сопровождением именно информационных систем), то можно выделить основные отличия. Так, при разработке информационных систем нужно использовать скорее формальные способы проектирования, в частности, CASE-системы. Это позволяет значительно легче обеспечить целостность проекта, чем при неформальном подходе. Не нужно забывать, что CASE-системы ориентированы преимущественно на разработку информационных систем, а потому хорошо для этого подходят. При разработке информационных систем несложно и весьма полезно ввести формальные методики оценки трудозатрат и производительности труда (число форм или отчетов в день). При разработке "наукоемкого" ПО применение формальных метрик может привести к раздуванию кода, что сказывается на его качестве. При производстве информационных систем оправдано более четкое разделение специалистов на "аналитиков", "проектировщиков" и "кодировщиков", поскольку на самом деле существует три задачи, требующие разных знаний и способностей: неформальное описание бизнес-процессов, создание проекта схемы данных, форм, отчетов и процедур с помощью CASE-системы и окончательная реализация проекта.
Литература
- Integrated Computer-Aided Manufucturing (ICAM). Architecture Part II. Volume IV _ Function Modeling Manual (IDEF0). SofTech. Waltham, June, 1981
- Information Modeling Manual. IDEF1 - Extended (IDEF1X). D. Appleton Company, Manhattan Beach, CA, December, 1985.
- Д. Марка, К. МакГоуэн. Методология структурного анализа и проектирования. M., МетаТехнология, 1993.
- Бьярн Страуструп. Язык программирования С++. Второе издание. Киев, Диасофт, 1993.
- Bertrand Meyer. Object-Oriented Software Construction. Second Edition. Published by Prentice Hall PTR Prentice Hall, Inc. 1997