Пользуясь возможностью, автор благодарит

· координатора академических программ компании IBM Алексея Полунина;

он сыграл роль дантовского Вергилия, введшего автора в сложный мир проблем объектно-ориентированного анализа и проектирования. На таких проводников можно положиться, несмотря на устрашающие надписи на входе («Оставь надежду всяк сюда входящий»);

· выпускницу факультета ВМК КГУ Анастасию Сабирзянову;

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

· компанию IBM - за программные средства и методические материалы, предоставленные в рамках программы « IBM Academic Initiative»

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

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


Глава 2. Перед UML. Программирование как моделирование: базовые понятия. Жизненный цикл разработки (lifecycle). Виденье (vision), виды (views) и деятели (actors).

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

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

Здесь принципиально важно понимать, что изначально мы совмещаем в себе все возможные, в том числе профессиональные роли – и только потому способны понимать других людей хотя бы в принципе. Хотя, разумеется, такое совмещение часто происходит в голове, не в реальности. «Папа» физически не может стать «мамой» - просто у каждого человека была своя мама. С другой стороны, «рыбак рыбака видит издалека» - мы лучше понимаем тот вид труда, в котором сами имеем больший опыт работы.

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

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

 

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

 

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

 

Любая модель содержит описание статики и динамики – состояний и изменений некоторого объекта внимания. Не обязательно некоторой вещи, материального объекта, но также ситуаций, связей, процессов… Проще говоря - всего того, что нам необходимо описать.

 

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

 

Объектно-ориентированный подход – принятый также и в UML – изначально ориентируется на разбиение описания статики и динамики моделируемого объекта на компактный набор взаимосвязанных подмоделей, содержащих совместное описание данных (свойства, properties) и процедур (методы, methods). Одновременно, в двух проекциях (ракурсах, планах, аспектах): более абстрактной, ранней и общей (классы) и более конкретной, специфичной и поздней (объекты).

 

Далее мы предполагаем в качестве предусловия

 

1) практическое знакомство читателя с основными принципами ООП и его

2) начальные теоретические познания современной математики – неформальное знакомство с основными идеями теории автоматов, теории графов, теории множеств и математической логики.

 

Естественно –лишь в рамках предыдущего университетского курса.

 

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

 

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

 

· Недостатками концептуальной модели (business model) - содержательного описания конкретной предметной области (domain) в целом, в ее статике и динамике (бизнес-процессов)

· Недостатками запроса, формулирующего требования к функциональности и иным качествам ПО (requirements) - описания того, что же именно мы собираемся автоматизировать.

 

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

 

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

 

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

 

Этот достаточно новый момент в понимании абстрагирования - выделение главного, отвлечения от деталей - как способа борьбы со сложностью стоит отметить особо. Все так делают, строя свои планы – не все люди закладываются на ошибки начальных планов и предусматривают возможность возврата, «отката» (rollback). Оттого (в частности) надежность не является объективной характеристикой самого ПО. Важность этого момента обусловлена и тем, что традиционные области применения ПО (точные науки, юриспруденция, бухгалтерский учет и т.п.) расширяются сегодня до крайне ответственного уровня [крупного] бизнеса – моделирования деятельности больших предприятий со сложной внутренней организацией. Проще говоря – результаты нашей работы начинают все более затрагивать все большее количество людей. Чем далее, тем более.

 

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

 

 

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

 

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

 

Детали подхода UML, переводящие многие привычные акценты программирования в иную – менее жесткую плоскость согласования видов работ с более размытыми границами, см. ниже. Но цель уже прозрачна – по мере возможности, нужно постараться облегчить всем участникам команды надежное прохождение всех последующих этапов. (Как увидим далее, в UML – на основе взаимности). Всем – по мере возможности, но в первую очередь – идущим следом программистам. Здесь мы четко видим новое назначение формальных схем высокого уровня абстракции (математики).

 

Особо отметим здесьнеобходимость контроля степени продвижения с учетом неизбежной последующей корректировки начальных планов (manage changes and assets) всеми участниками процесса разработки.

 

Manage, англ. – не только (и не столько) «управлять», но и «справляться». В том числе - с проблемой, задачей, внезапно возникшей в ходе дела трудностью и т.п. В данном случае речь идет о продвижении (asset – ценное, приобретенное, достигнутое) и изменении (changes) относительно первоначальных планов. В общей концепции современного менеджмента как управления проектами – в том числе, проектами по разработке ПО - важно заметить то, что оно ставит своей целью контроль не над людьми, но возникающими в процессе их рабочего взаимодействия проблемами и направленными на решение этих проблем соглашениями (agreements, от agree – согласится, быть согласным). Центральный вопрос здесь – не кто кем управляет, но кто за что отвечает. За результат работы отвечают все – за конкретный вид работ отвечает специалист. Желательно – высококвалифицированный.

 

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

 

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

 

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

 

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

 

 

 

Оставшиеся, более «приземленные» этапы жизненного цикла (lifecycle) разработки ПО не рассматриваются глубоко в данном пособии. Конечно же – не потому, что они не важны. Напротив. Работа на каждом этапе должны по мере возможности облегчать прохождение последующих. Но при этом мы можем исходить лишь из принципиального понимания их сути – заведомо не зная во всей полноте возникающих внутри них сложностей.

 

Здесь отметим своеобразное преломление центральной для кибернетики идеи «черного ящика» и созвучных ей идей инкапсуляции (сокрытия, hiding) в программировании. Находясь «вне», мы не знаем всех сложностей «внутри» – точно зная лишь то, что на деле «внутри» все сложно.

 

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

 

Этап развертывания (deploy) имеет дело с проблемами внедрения ПО в конкретной физической среде – с учетом особенностей устройства (архитектуры) конкретных компьютеров, специфики построения компьютерной сети и т.п.

 

Как мы хорошо знаем, на этапе программирования такой учет специфики «железа» (т.е. знание логической схемы построения физических устройств) может сделать систему более эффективной, в чисто вычислительном значении термина. И, одновременно, менее надежной. В целом – менее масштабируемой и гибкой, стабильной, устойчивой при непредвиденных ранее изменениях. В еще большей степени это относиться к этапу анализа и проектирования.

 

Этап сопровождения (manage) решает организационные проблемы внедрения ПО в конкретной социальной среде, организации.

 

Здесь облегчает дело то, что типов организации не так уж много. Усложняет - то, что «типов» людей – ровно столько, сколько самих людей. Проще говоря, все люди абсолютно индивидуальны. Собственно, лучше решать проблему согласованной работы самых разных людей и помогает нам UML. Хотя, разумеется, не нужно быть высококвалифицированным менеджером, чтобы понимать, что никакая технология не решит за нас наши проблемы - автоматически.

 

Ключевым в понятии жизненного цикла ПО (lifecycle) понятие версии – как результата работы, подлежащего последующей оптимизации (optimization). Здесь имеется в виду проблема дальнейшего улучшения качества ПО – уже не только в более привычном специальном значении (вычислительная оптимизация), но и в самом широком понимании термина «качественное, хорошее».

 

Из-за чего результат работы может быть не идеальным, не совершенным и не полным – а потому не может считаться законченным? Мы помним, как в программировании термин ошибка (error) постепенно заменился более общим термином исключение (exception). Зачастую, но далеко не всегда недостатки результата работы – это ошибки разработчиков. После окончания работ выясняется, что те или иные, большие или мелкие недостатки были допущены на всех предыдущих этапах – начиная с этапа неформальной постановки задачи ее заказчиком.

 

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

 

Что нам видеть в понятии жизненного цикла?

 

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

 

Только принципиальных – но далеко не всех возможных.

 

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

 

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

 

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

 


Глава 3. Как понимать UML? Каскадный и инкрементный подход к разработке ПО.

 

Математика - это язык. Исаак Ньютон.[4]

 

Слова, слова… UML – взятый «сам по себе», вне контекста его происхождения и назначения - будет для нас лишь еще одним набором обозначений, если не видеть сутью нового для нас языка некий качественно новый методологический подход, за которым стоит огромный опыт разработчиков.

 

Больше того. Все мы начинаем изучение программирования с «картинок» - блок-схем, автоматных диаграмм, графов и т.п. схем. Очевидно (в самом буквальном значении слова), что возврат создателями UML к диаграммам, визуальному представлению знаний - в определенном смысле, есть шаг назад по сравнению с куда более изощренными языками вроде современных языков и сред программирования.

 

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

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

 

Иными словами, по факту своего происхождения UML связывается с «моделированием процесса моделирования (процесса разработки моделей)» - предварительным описанием моделей программных систем, направленном на снижение рисков неудачной разработки. В особенности тесна генетическая связь UML с итеративным подходом к разработке таких систем.

 

Далее, по мере детализации (конкретизации, приближения к реализации на практике) подход (идея, «философия», «идеология») перерастает в методологию. Далее - в технологию. Классический пример связанной с итеративным подходом технологии - Rational Unified Process (RUP).

 

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

 

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

 

Выше мы постарались очертить происхождение разных специализаций как разделения труда во времени и между людьми - по мере возрастания сложности разработки. Не стоит «стрелять из пушки по воробьям» (вполне очевидное исключение здесь составляют цели обучения). Не трогай того, что работает – пока оно работает достаточно хорошо …

 

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

 

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

 

Каскадный подход предполагает строго последовательное выполнение этапов:

1. Во времени: следующий этап должен начаться не ранее предыдущего, и

2. Связь по результату: участник предыдущего этапа должен передать законченный итог своей работы участникам последующего.

 

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

 

Теперь мы не продвигаемся к конечной цели согласно жизненному циклу – мы стараемся (по мере возможности) продвинуть каждый этап жизненного цикла. Вместе (а не один за счет другого). Т.е. сам цикл работ – со всеми ее этапами.

 

Параллелизм здесь не означает полной независимости. Совсем наоборот. Для лучшего понимания нового для нас подхода, вспомним столь знаменитое в раннем программировании «разделяй и властвуй». Есть кардинальная разница между стремлением продвинуть работу и продвинуться самому. Разделяй – сложность работы, властвуй – над собой. В основе нашей работы лежат ранние, уже существующие концептуальные модели той или иной формы организации работ, но и они постоянно изменяются. Прощай, Цезарь…

 

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

 

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

 

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

 

Словом, здесь мы рискуем попасть в тупиковую ситуацию, известную в программировании как deadlock («заклинивание»). Следуя заданной программе, каждый ничего не может сделать, потому что ждет для начала своей работы окончания работы другого. И так – для каждого вида работ…

 

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

 

См. на диаграмме примерный ход разработки при итеративном подходе.

 

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

 

Практические рекомендации для определения длительности и количества итераций в зависимости от предполагаемой длительности проекта и выделенных на него ресурсов можно найти в [Larman].

 

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

 

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

 

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

 

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

 


Глава 3. Как применять UML? Обзор языка «с высоты птичьего полета».

 

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

 

При этом мы будем уделять больше внимания на моменты, хуже нам знакомые – особенно, на понятии прецедента. Впрочем, как известно, «новое – это хорошо забытое старое». Точнее, с точки зрения автора – это вспомненное и по-иному, лучше понятое старое. Дело не в том, что мы не знакомы с чем-то вообще – это исключение. Как правило – мы встречали все это ранее. В более простых ситуациях – и именно поэтому мы не придаем этому особого значения. До тех, пока… гром не грянет, мужик не перекреститься.

 

Проблема масштабирования обычно трактуется сегодня как возрастание некоторого количества. Например, если пользователь один и стоит рядом (а еще лучше – если это ты сам) – все просто. А если - миллион? Но более существенная проблема состоит в убывании. Обычно мы предполагаем некий автоматизм (само собой!) сохранения того простого (в целом - хорошего), что имеем. Что имеем – не храним, потерявши плачем.

 

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

 

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

 

  • UML – не чисто визуальный язык. Диаграммы формулируют только основное текущее согласие участников в понимании системы, достигнутом на какой-то стадии разработки. Детали соглашения (в том числе, спорные) фиксируются неформально в комментариях, являющихся неотъемлемой частью каждой диаграммы.
  • Разные типы диаграмм дают разный взгляд (проекции) на те или иные аспекты - стороны функционирования или строения (архитектуры) системы. Диаграммы могут содержать одну и ту же информацию (проекции не ортогональны) и
  • Одна диаграмма может служить уточнением другой, т.е. служить частичным описанием некоторого аспекта поведения или строения системы. Именно описывающий один аспект группу взаимосвязанных по тематике и/или времени диаграмм называют в UML view, т.е. представление или взгляд на разработку с точки зрения того или иного участника разработки. Точнее, ролью участника на границе смежных этапов «жизненного цикла разработки ПО». В русском переводе, их обычно также называют моделью [относящейся к заданной теме]. Скажем, модель приложения связана с границей «проектирование и программная реализация», модель предметной области – с границей «анализа и бизнес-моделирование». Во избежание путаницы, далее в этом случае мы предпочитаем на равной основе говорить просто о задаче описания. Всегда подразумевается - описания частичного, незавершенного. Единственным законченным описанием служит лишь результат разработки в виде завершенной, готовой к использованию версии программной системы.

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

 

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

 

  • Когда именно какие типы диаграмм в каком порядке нужно использовать? Универсального «алгоритма разработки ПО» – нет. А потому это крайне сложный вопрос, сильно зависящий от конкретной задачи (см. пример разработки далее) – и квалификации конкретного разработчика. В каком порядке пробовать ту или иную форму того или иного типа диаграммы? Ответ (на словах) более простой – нужно знать эволюцию (историю) своего дела. Она шла от простого к сложному. Первый шажок в понимании этой эволюции (с опорой на уже имеющиеся у читателя знания и умения[5]) мы и попытаемся сейчас сделать.

 

 

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